Decode and display any received SPD InfoFrame in log-status.

Signed-off-by: Martin Bugge <marbu...@cisco.com>
---
 drivers/media/i2c/adv7842.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 5d79c57..805a117 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -2243,6 +2243,81 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
                v4l2_info(sd, "\t%s %s\n", y10_txt[avi.y10], q10_txt[avi.q10]);
 }
 
+static const char *sdi_txt(u8 code)
+{
+       switch (code) {
+       case 0x00: return "unknown";
+       case 0x01: return "Digital STB";
+       case 0x02: return "DVD player";
+       case 0x03: return "D-VHS";
+       case 0x04: return "HDD Videorecorder";
+       case 0x05: return "DVC";
+       case 0x06: return "DSC";
+       case 0x07: return "Video CD";
+       case 0x08: return "Game";
+       case 0x09: return "PC general";
+       case 0x0a: return "Blu-Ray Disc (BD)";
+       case 0x0b: return "Super Audio CD";
+       }
+       return "Reserved";
+}
+
+static void print_spd_info_frame(struct v4l2_subdev *sd)
+{
+       int i;
+       u8 spd_type;
+       u8 spd_ver;
+       u8 spd_len;
+       u8 spd_crc;
+       u8 buf[32];
+       u8 vn[8];
+       u8 pd[16];
+       u8 sdi;
+
+       if (!(hdmi_read(sd, 0x05) & 0x80)) {
+               v4l2_info(sd, "receive DVI-D signal (SDP infoframe not 
supported)\n");
+               return;
+       }
+       if (!(io_read(sd, 0x60) & 0x04)) {
+               v4l2_info(sd, "SDP infoframe not received\n");
+               return;
+       }
+
+       if (io_read(sd, 0x88) & 0x40) {
+               v4l2_info(sd, "SPD infoframe checksum error has occurred 
earlier\n");
+               io_write(sd, 0x8a, 0x40); /* clear SPD_INF_CKS_ERR_RAW */
+               if (io_read(sd, 0x88) & 0x40) {
+                       v4l2_info(sd, "SPD infoframe checksum error still 
present\n");
+                       io_write(sd, 0x8a, 0x40); /* clear SPD_INF_CKS_ERR_RAW 
*/
+               }
+       }
+
+       spd_type = infoframe_read(sd, 0xe6) & 0x7f;
+       spd_ver = infoframe_read(sd, 0xe7);
+       spd_len = infoframe_read(sd, 0xe8);
+       spd_crc = infoframe_read(sd, 0x2a);
+
+       v4l2_info(sd, "SPD infoframe type %d, version %d, crc 0x%x, len %d\n",
+                 spd_type, spd_ver, spd_crc, spd_len);
+
+       if (spd_type != 0x03)
+               return;
+       if (spd_ver != 0x01)
+               return;
+
+       memset(buf, 0, sizeof(buf));
+       for (i = 0; i < 25 && i < spd_len; i++)
+               buf[i] = infoframe_read(sd, i + 0x2b);
+
+       snprintf(vn, 8, buf);
+       snprintf(pd, 16, buf + 8);
+       sdi = buf[24];
+
+       v4l2_info(sd, "\tVendor Name: %s\n", vn);
+       v4l2_info(sd, "\tProduct Description: %s\n", pd);
+       v4l2_info(sd, "\tSource Device Information: %s (%d)\n", sdi_txt(sdi), 
sdi);
+}
+
 static const char * const prim_mode_txt[] = {
        "SDP",
        "Component",
@@ -2455,6 +2530,7 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd)
                        deep_color_mode_txt[hdmi_read(sd, 0x0b) >> 6]);
 
        print_avi_infoframe(sd);
+       print_spd_info_frame(sd);
        return 0;
 }
 
-- 
1.8.5.3

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to