aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/adv7604.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-10-16 09:12:55 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-11-21 15:12:20 -0500
commitcf9afb1dafaf1ffeffbb4acdb5adf255e8a2aa76 (patch)
tree5149fba71f7d3b77c7c1fb2fb991510fa2f48f63 /drivers/media/i2c/adv7604.c
parentccbd5bc448ec782af7d1f3f68bd450c9c38015a0 (diff)
[media] adv7604: restart STDI once if format is not found
The STDI block may measure wrong values, especially for lcvs and lcf. If the driver can not find any valid timing, the STDI block is restarted to measure the video timings again. The function will return an error, but the restart of STDI will generate a new STDI interrupt and the format detection process will restart. Signed-off-by: Mats Randgaard <matrandg@cisco.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c/adv7604.c')
-rw-r--r--drivers/media/i2c/adv7604.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 88b7984a4188..05f8950f6f91 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -76,6 +76,7 @@ struct adv7604_state {
76 struct workqueue_struct *work_queues; 76 struct workqueue_struct *work_queues;
77 struct delayed_work delayed_work_enable_hotplug; 77 struct delayed_work delayed_work_enable_hotplug;
78 bool connector_hdmi; 78 bool connector_hdmi;
79 bool restart_stdi_once;
79 80
80 /* i2c clients */ 81 /* i2c clients */
81 struct i2c_client *i2c_avlink; 82 struct i2c_client *i2c_avlink;
@@ -1297,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1297 stdi.lcvs -= 2; 1298 stdi.lcvs -= 2;
1298 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); 1299 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
1299 if (stdi2dv_timings(sd, &stdi, timings)) { 1300 if (stdi2dv_timings(sd, &stdi, timings)) {
1301 /*
1302 * The STDI block may measure wrong values, especially
1303 * for lcvs and lcf. If the driver can not find any
1304 * valid timing, the STDI block is restarted to measure
1305 * the video timings again. The function will return an
1306 * error, but the restart of STDI will generate a new
1307 * STDI interrupt and the format detection process will
1308 * restart.
1309 */
1310 if (state->restart_stdi_once) {
1311 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
1312 /* TODO restart STDI for Sync Channel 2 */
1313 /* enter one-shot mode */
1314 cp_write_and_or(sd, 0x86, 0xf9, 0x00);
1315 /* trigger STDI restart */
1316 cp_write_and_or(sd, 0x86, 0xf9, 0x04);
1317 /* reset to continuous mode */
1318 cp_write_and_or(sd, 0x86, 0xf9, 0x02);
1319 state->restart_stdi_once = false;
1320 return -ENOLINK;
1321 }
1300 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); 1322 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
1301 return -ERANGE; 1323 return -ERANGE;
1302 } 1324 }
1325 state->restart_stdi_once = true;
1303 } 1326 }
1304found: 1327found:
1305 1328
@@ -2026,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client,
2026 v4l2_err(sd, "failed to create all i2c clients\n"); 2049 v4l2_err(sd, "failed to create all i2c clients\n");
2027 goto err_i2c; 2050 goto err_i2c;
2028 } 2051 }
2052 state->restart_stdi_once = true;
2029 2053
2030 /* work queues */ 2054 /* work queues */
2031 state->work_queues = create_singlethread_workqueue(client->name); 2055 state->work_queues = create_singlethread_workqueue(client->name);