|
@@ -76,6 +76,7 @@ struct adv7604_state {
|
|
|
struct workqueue_struct *work_queues;
|
|
|
struct delayed_work delayed_work_enable_hotplug;
|
|
|
bool connector_hdmi;
|
|
|
+ bool restart_stdi_once;
|
|
|
|
|
|
/* i2c clients */
|
|
|
struct i2c_client *i2c_avlink;
|
|
@@ -1297,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
|
|
|
stdi.lcvs -= 2;
|
|
|
v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
|
|
|
if (stdi2dv_timings(sd, &stdi, timings)) {
|
|
|
+ /*
|
|
|
+ * 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.
|
|
|
+ */
|
|
|
+ if (state->restart_stdi_once) {
|
|
|
+ v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
|
|
|
+ /* TODO restart STDI for Sync Channel 2 */
|
|
|
+ /* enter one-shot mode */
|
|
|
+ cp_write_and_or(sd, 0x86, 0xf9, 0x00);
|
|
|
+ /* trigger STDI restart */
|
|
|
+ cp_write_and_or(sd, 0x86, 0xf9, 0x04);
|
|
|
+ /* reset to continuous mode */
|
|
|
+ cp_write_and_or(sd, 0x86, 0xf9, 0x02);
|
|
|
+ state->restart_stdi_once = false;
|
|
|
+ return -ENOLINK;
|
|
|
+ }
|
|
|
v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
|
|
|
return -ERANGE;
|
|
|
}
|
|
|
+ state->restart_stdi_once = true;
|
|
|
}
|
|
|
found:
|
|
|
|
|
@@ -2026,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client,
|
|
|
v4l2_err(sd, "failed to create all i2c clients\n");
|
|
|
goto err_i2c;
|
|
|
}
|
|
|
+ state->restart_stdi_once = true;
|
|
|
|
|
|
/* work queues */
|
|
|
state->work_queues = create_singlethread_workqueue(client->name);
|