media: vivid: vidioc_g_edid: do not change the original input EDID
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Mon, 24 Jun 2024 09:52:58 +0000 (12:52 +0300)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Fri, 28 Jun 2024 06:00:29 +0000 (08:00 +0200)
Returning an EDID for a connected output would modify the original
input EDID with the physical address of the output. That causes
problems, and it should just update the physical address of the
output EDID.

Update vivid_hdmi_edid to set the physical address to 0.0.0.0.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/test-drivers/vivid/vivid-core.c
drivers/media/test-drivers/vivid/vivid-vid-common.c

index 0273bc9863b03aff830eb68ee094a98ae98070dc..4a9d9b30aa422a7fb7bc278fe6a86f7e04dcbd63 100644 (file)
@@ -218,7 +218,7 @@ static const u8 vivid_hdmi_edid[256] = {
        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,
+       0x0c, 0x00, 0x00, 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,
@@ -229,7 +229,7 @@ static const u8 vivid_hdmi_edid[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, 0x82,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92,
 };
 
 static int vidioc_querycap(struct file *file, void  *priv,
index 38d788b5cf196f8c62b426bee3295b9523019db8..a3e8eb90f11b1acfd911677b6b0b817e5ac8aef0 100644 (file)
@@ -1038,6 +1038,7 @@ int vidioc_g_edid(struct file *file, void *_fh,
        struct vivid_dev *dev = video_drvdata(file);
        struct video_device *vdev = video_devdata(file);
        struct cec_adapter *adap;
+       unsigned int loc;
 
        memset(edid->reserved, 0, sizeof(edid->reserved));
        if (vdev->vfl_dir == VFL_DIR_RX) {
@@ -1068,8 +1069,25 @@ int vidioc_g_edid(struct file *file, void *_fh,
                return -EINVAL;
        if (edid->blocks > dev->edid_blocks - edid->start_block)
                edid->blocks = dev->edid_blocks - edid->start_block;
-       if (adap)
-               v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
+
        memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
+
+       loc = cec_get_edid_spa_location(dev->edid, dev->edid_blocks * 128);
+       if (vdev->vfl_dir == VFL_DIR_TX && adap && loc &&
+           loc >= edid->start_block * 128 &&
+           loc < (edid->start_block + edid->blocks) * 128) {
+               unsigned int i;
+               u8 sum = 0;
+
+               loc -= edid->start_block * 128;
+               edid->edid[loc] = adap->phys_addr >> 8;
+               edid->edid[loc + 1] = adap->phys_addr & 0xff;
+               loc &= ~0x7f;
+
+               /* update the checksum */
+               for (i = loc; i < loc + 127; i++)
+                       sum += edid->edid[i];
+               edid->edid[i] = 256 - sum;
+       }
        return 0;
 }