summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Bugge <marbugge@cisco.com>2013-12-10 09:00:05 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 05:28:06 -0200
commita6c98f56e7f4a46358ea4b10f40df419f9679e37 (patch)
tree17fc8ccbb35522a3e8f8ecdca2a50f7f10ae2019
parent51af70bf93592c51d1ed8db421bb6cce8a9aed2d (diff)
downloadop-kernel-dev-a6c98f56e7f4a46358ea4b10f40df419f9679e37.zip
op-kernel-dev-a6c98f56e7f4a46358ea4b10f40df419f9679e37.tar.gz
[media] ad9389b: retry setup if the state is inconsistent
Retry setup if the device is powered off when it should be powered on. This state can be caused by rapid hotplug toggles. Signed-off-by: Martin Bugge <marbugge@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/i2c/ad9389b.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index cca7758..83225d6 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -904,7 +904,7 @@ static void ad9389b_notify_monitor_detect(struct v4l2_subdev *sd)
v4l2_subdev_notify(sd, AD9389B_MONITOR_DETECT, (void *)&mdt);
}
-static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
+static void ad9389b_update_monitor_present_status(struct v4l2_subdev *sd)
{
struct ad9389b_state *state = get_ad9389b_state(sd);
/* read hotplug and rx-sense state */
@@ -947,6 +947,31 @@ static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
ad9389b_s_ctrl(state->hdmi_mode_ctrl);
}
+static void ad9389b_check_monitor_present_status(struct v4l2_subdev *sd)
+{
+ struct ad9389b_state *state = get_ad9389b_state(sd);
+ int retry = 0;
+
+ ad9389b_update_monitor_present_status(sd);
+
+ /*
+ * Rapid toggling of the hotplug may leave the chip powered off,
+ * even if we think it is on. In that case reset and power up again.
+ */
+ while (state->power_on && (ad9389b_rd(sd, 0x41) & 0x40)) {
+ if (++retry > 5) {
+ v4l2_err(sd, "retried %d times, give up\n", retry);
+ return;
+ }
+ v4l2_dbg(1, debug, sd, "%s: reset and re-check status (%d)\n", __func__, retry);
+ ad9389b_notify_monitor_detect(sd);
+ cancel_delayed_work_sync(&state->edid_handler);
+ memset(&state->edid, 0, sizeof(struct ad9389b_state_edid));
+ ad9389b_s_power(sd, false);
+ ad9389b_update_monitor_present_status(sd);
+ }
+}
+
static bool edid_block_verify_crc(u8 *edid_block)
{
u8 sum = 0;
OpenPOWER on IntegriCloud