Commit 7de6fab1 authored by Mats Randgaard's avatar Mats Randgaard Committed by Mauro Carvalho Chehab

[media] adv7842: Use defines to select EDID port

Signed-off-by: default avatarMats Randgaard <matrandg@cisco.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 77a09f8b
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
* References (c = chapter, p = page): * References (c = chapter, p = page):
* REF_01 - Analog devices, ADV7842, Register Settings Recommendations, * REF_01 - Analog devices, ADV7842, Register Settings Recommendations,
* Revision 2.5, June 2010 * Revision 2.5, June 2010
* REF_02 - Analog devices, Register map documentation, Documentation of * REF_02 - Analog devices, Software User Guide, UG-206,
* the register maps, Software manual, Rev. F, June 2010 * ADV7842 I2C Register Maps, Rev. 0, November 2010
*/ */
...@@ -587,10 +587,10 @@ static void adv7842_delayed_work_enable_hotplug(struct work_struct *work) ...@@ -587,10 +587,10 @@ static void adv7842_delayed_work_enable_hotplug(struct work_struct *work)
v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n", v4l2_dbg(2, debug, sd, "%s: enable hotplug on ports: 0x%x\n",
__func__, present); __func__, present);
if (present & 0x1) if (present & (0x04 << ADV7842_EDID_PORT_A))
mask |= 0x20; /* port A */ mask |= 0x20;
if (present & 0x2) if (present & (0x04 << ADV7842_EDID_PORT_B))
mask |= 0x10; /* port B */ mask |= 0x10;
io_write_and_or(sd, 0x20, 0xcf, mask); io_write_and_or(sd, 0x20, 0xcf, mask);
} }
...@@ -679,14 +679,12 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) ...@@ -679,14 +679,12 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_client *client = v4l2_get_subdevdata(sd);
struct adv7842_state *state = to_state(sd); struct adv7842_state *state = to_state(sd);
const u8 *val = state->hdmi_edid.edid; const u8 *val = state->hdmi_edid.edid;
u8 cur_mask = rep_read(sd, 0x77) & 0x0c;
u8 mask = port == 0 ? 0x4 : 0x8;
int spa_loc = edid_spa_location(val); int spa_loc = edid_spa_location(val);
int err = 0; int err = 0;
int i; int i;
v4l2_dbg(2, debug, sd, "%s: write EDID on port %d (spa at 0x%x)\n", v4l2_dbg(2, debug, sd, "%s: write EDID on port %c (spa at 0x%x)\n",
__func__, port, spa_loc); __func__, (port == ADV7842_EDID_PORT_A) ? 'A' : 'B', spa_loc);
/* HPA disable on port A and B */ /* HPA disable on port A and B */
io_write_and_or(sd, 0x20, 0xcf, 0x00); io_write_and_or(sd, 0x20, 0xcf, 0x00);
...@@ -703,44 +701,32 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port) ...@@ -703,44 +701,32 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
if (err) if (err)
return err; return err;
if (spa_loc > 0) { if (spa_loc < 0)
if (port == 0) { spa_loc = 0xc0; /* Default value [REF_02, p. 199] */
/* port A SPA */
rep_write(sd, 0x72, val[spa_loc]); if (port == ADV7842_EDID_PORT_A) {
rep_write(sd, 0x73, val[spa_loc + 1]); rep_write(sd, 0x72, val[spa_loc]);
} else { rep_write(sd, 0x73, val[spa_loc + 1]);
/* port B SPA */
rep_write(sd, 0x74, val[spa_loc]);
rep_write(sd, 0x75, val[spa_loc + 1]);
}
rep_write(sd, 0x76, spa_loc);
} else { } else {
/* Edid values for SPA location */ rep_write(sd, 0x74, val[spa_loc]);
if (port == 0) { rep_write(sd, 0x75, val[spa_loc + 1]);
/* port A */
rep_write(sd, 0x72, val[0xc0]);
rep_write(sd, 0x73, val[0xc1]);
} else {
/* port B */
rep_write(sd, 0x74, val[0xc0]);
rep_write(sd, 0x75, val[0xc1]);
}
rep_write(sd, 0x76, 0xc0);
} }
rep_write_and_or(sd, 0x77, 0xbf, 0x00); rep_write(sd, 0x76, spa_loc & 0xff);
rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40);
/* Calculates the checksums and enables I2C access to internal /* Calculates the checksums and enables I2C access to internal
* EDID ram from HDMI DDC ports * EDID ram from HDMI DDC ports
*/ */
rep_write_and_or(sd, 0x77, 0xf3, mask | cur_mask); rep_write_and_or(sd, 0x77, 0xf3, state->hdmi_edid.present);
for (i = 0; i < 1000; i++) { for (i = 0; i < 1000; i++) {
if (rep_read(sd, 0x7d) & mask) if (rep_read(sd, 0x7d) & state->hdmi_edid.present)
break; break;
mdelay(1); mdelay(1);
} }
if (i == 1000) { if (i == 1000) {
v4l_err(client, "error enabling edid on port %d\n", port); v4l_err(client, "error enabling edid on port %c\n",
(port == ADV7842_EDID_PORT_A) ? 'A' : 'B');
return -EIO; return -EIO;
} }
...@@ -1888,7 +1874,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e) ...@@ -1888,7 +1874,7 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
struct adv7842_state *state = to_state(sd); struct adv7842_state *state = to_state(sd);
int err = 0; int err = 0;
if (e->pad > 2) if (e->pad > ADV7842_EDID_PORT_VGA)
return -EINVAL; return -EINVAL;
if (e->start_block != 0) if (e->start_block != 0)
return -EINVAL; return -EINVAL;
...@@ -1901,20 +1887,25 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e) ...@@ -1901,20 +1887,25 @@ static int adv7842_set_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *e)
state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15], state->aspect_ratio = v4l2_calc_aspect_ratio(e->edid[0x15],
e->edid[0x16]); e->edid[0x16]);
if (e->pad == 2) { switch (e->pad) {
case ADV7842_EDID_PORT_VGA:
memset(&state->vga_edid.edid, 0, 256); memset(&state->vga_edid.edid, 0, 256);
state->vga_edid.present = e->blocks ? 0x1 : 0x0; state->vga_edid.present = e->blocks ? 0x1 : 0x0;
memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks); memcpy(&state->vga_edid.edid, e->edid, 128 * e->blocks);
err = edid_write_vga_segment(sd); err = edid_write_vga_segment(sd);
} else { break;
u32 mask = 0x1<<e->pad; case ADV7842_EDID_PORT_A:
case ADV7842_EDID_PORT_B:
memset(&state->hdmi_edid.edid, 0, 256); memset(&state->hdmi_edid.edid, 0, 256);
if (e->blocks) if (e->blocks)
state->hdmi_edid.present |= mask; state->hdmi_edid.present |= 0x04 << e->pad;
else else
state->hdmi_edid.present &= ~mask; state->hdmi_edid.present &= ~(0x04 << e->pad);
memcpy(&state->hdmi_edid.edid, e->edid, 128*e->blocks); memcpy(&state->hdmi_edid.edid, e->edid, 128 * e->blocks);
err = edid_write_hdmi_segment(sd, e->pad); err = edid_write_hdmi_segment(sd, e->pad);
break;
default:
return -EINVAL;
} }
if (err < 0) if (err < 0)
v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad); v4l2_err(sd, "error %d writing edid on port %d\n", err, e->pad);
......
...@@ -225,4 +225,8 @@ struct adv7842_platform_data { ...@@ -225,4 +225,8 @@ struct adv7842_platform_data {
* deinterlacer. */ * deinterlacer. */
#define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE) #define ADV7842_CMD_RAM_TEST _IO('V', BASE_VIDIOC_PRIVATE)
#define ADV7842_EDID_PORT_A 0
#define ADV7842_EDID_PORT_B 1
#define ADV7842_EDID_PORT_VGA 2
#endif #endif
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