Commit 54b74981 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: adv7604: writing a one-block EDID failed

The adv7604 refused to accept an one-block EDID, it required two blocks.

Fix this.
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent abe1338c
...@@ -2298,7 +2298,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ...@@ -2298,7 +2298,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
struct adv76xx_state *state = to_state(sd); struct adv76xx_state *state = to_state(sd);
const struct adv76xx_chip_info *info = state->info; const struct adv76xx_chip_info *info = state->info;
unsigned int spa_loc; unsigned int spa_loc;
u16 pa; u16 pa, parent_pa;
int err; int err;
int i; int i;
...@@ -2332,7 +2332,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ...@@ -2332,7 +2332,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
return -E2BIG; return -E2BIG;
} }
pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc); pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc);
err = v4l2_phys_addr_validate(pa, &pa, NULL); err = v4l2_phys_addr_validate(pa, &parent_pa, NULL);
if (err) if (err)
return err; return err;
...@@ -2348,25 +2348,25 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ...@@ -2348,25 +2348,25 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
* Return an error if no location of the source physical address * Return an error if no location of the source physical address
* was found. * was found.
*/ */
if (spa_loc == 0) if (edid->blocks > 1 && spa_loc == 0)
return -EINVAL; return -EINVAL;
switch (edid->pad) { switch (edid->pad) {
case ADV76XX_PAD_HDMI_PORT_A: case ADV76XX_PAD_HDMI_PORT_A:
state->spa_port_a[0] = edid->edid[spa_loc]; state->spa_port_a[0] = pa >> 8;
state->spa_port_a[1] = edid->edid[spa_loc + 1]; state->spa_port_a[1] = pa & 0xff;
break; break;
case ADV7604_PAD_HDMI_PORT_B: case ADV7604_PAD_HDMI_PORT_B:
rep_write(sd, 0x70, edid->edid[spa_loc]); rep_write(sd, 0x70, pa >> 8);
rep_write(sd, 0x71, edid->edid[spa_loc + 1]); rep_write(sd, 0x71, pa & 0xff);
break; break;
case ADV7604_PAD_HDMI_PORT_C: case ADV7604_PAD_HDMI_PORT_C:
rep_write(sd, 0x72, edid->edid[spa_loc]); rep_write(sd, 0x72, pa >> 8);
rep_write(sd, 0x73, edid->edid[spa_loc + 1]); rep_write(sd, 0x73, pa & 0xff);
break; break;
case ADV7604_PAD_HDMI_PORT_D: case ADV7604_PAD_HDMI_PORT_D:
rep_write(sd, 0x74, edid->edid[spa_loc]); rep_write(sd, 0x74, pa >> 8);
rep_write(sd, 0x75, edid->edid[spa_loc + 1]); rep_write(sd, 0x75, pa & 0xff);
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -2381,8 +2381,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ...@@ -2381,8 +2381,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
rep_write_clr_set(sd, 0x71, 0x01, (spa_loc & 0x100) >> 8); rep_write_clr_set(sd, 0x71, 0x01, (spa_loc & 0x100) >> 8);
} }
edid->edid[spa_loc] = state->spa_port_a[0]; if (spa_loc) {
edid->edid[spa_loc + 1] = state->spa_port_a[1]; edid->edid[spa_loc] = state->spa_port_a[0];
edid->edid[spa_loc + 1] = state->spa_port_a[1];
}
memcpy(state->edid.edid, edid->edid, 128 * edid->blocks); memcpy(state->edid.edid, edid->edid, 128 * edid->blocks);
state->edid.blocks = edid->blocks; state->edid.blocks = edid->blocks;
...@@ -2409,7 +2411,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) ...@@ -2409,7 +2411,7 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
v4l2_err(sd, "error enabling edid (0x%x)\n", state->edid.present); v4l2_err(sd, "error enabling edid (0x%x)\n", state->edid.present);
return -EIO; return -EIO;
} }
cec_s_phys_addr(state->cec_adap, pa, false); cec_s_phys_addr(state->cec_adap, parent_pa, false);
/* enable hotplug after 100 ms */ /* enable hotplug after 100 ms */
schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10); schedule_delayed_work(&state->delayed_work_enable_hotplug, HZ / 10);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment