aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Bugge <marbugge@cisco.com>2013-12-10 10:00:06 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 03:35:46 -0500
commit6e9071f26864d83be6855f570a5ccc847b66028a (patch)
treeade746adf803b655ff0b9ddaeb309a18d41cdd84
parentfc2e991e86382abb5cd32010b92a63b15bd76f30 (diff)
[media] adv7842: 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. Copied from adv7604. Signed-off-by: Martin Bugge <marbugge@cisco.com> Cc: Mats Randgaard <matrandg@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/adv7842.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index eab9a1b8b54b..ae7252c1cd0c 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -85,6 +85,7 @@ struct adv7842_state {
85 bool is_cea_format; 85 bool is_cea_format;
86 struct workqueue_struct *work_queues; 86 struct workqueue_struct *work_queues;
87 struct delayed_work delayed_work_enable_hotplug; 87 struct delayed_work delayed_work_enable_hotplug;
88 bool restart_stdi_once;
88 bool hdmi_port_a; 89 bool hdmi_port_a;
89 90
90 /* i2c clients */ 91 /* i2c clients */
@@ -1345,6 +1346,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
1345 1346
1346 /* read STDI */ 1347 /* read STDI */
1347 if (read_stdi(sd, &stdi)) { 1348 if (read_stdi(sd, &stdi)) {
1349 state->restart_stdi_once = true;
1348 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__); 1350 v4l2_dbg(1, debug, sd, "%s: no valid signal\n", __func__);
1349 return -ENOLINK; 1351 return -ENOLINK;
1350 } 1352 }
@@ -1355,6 +1357,7 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
1355 uint32_t freq; 1357 uint32_t freq;
1356 1358
1357 timings->type = V4L2_DV_BT_656_1120; 1359 timings->type = V4L2_DV_BT_656_1120;
1360
1358 bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08); 1361 bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08);
1359 bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a); 1362 bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a);
1360 freq = (hdmi_read(sd, 0x06) * 1000000) + 1363 freq = (hdmi_read(sd, 0x06) * 1000000) +
@@ -1391,21 +1394,50 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
1391 } 1394 }
1392 adv7842_fill_optional_dv_timings_fields(sd, timings); 1395 adv7842_fill_optional_dv_timings_fields(sd, timings);
1393 } else { 1396 } else {
1394 /* Interlaced? */ 1397 /* find format
1395 if (stdi.interlaced) { 1398 * Since LCVS values are inaccurate [REF_03, p. 339-340],
1396 v4l2_dbg(1, debug, sd, "%s: interlaced video not supported\n", __func__); 1399 * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
1397 return -ERANGE; 1400 */
1398 } 1401 if (!stdi2dv_timings(sd, &stdi, timings))
1399 1402 goto found;
1403 stdi.lcvs += 1;
1404 v4l2_dbg(1, debug, sd, "%s: lcvs + 1 = %d\n", __func__, stdi.lcvs);
1405 if (!stdi2dv_timings(sd, &stdi, timings))
1406 goto found;
1407 stdi.lcvs -= 2;
1408 v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
1400 if (stdi2dv_timings(sd, &stdi, timings)) { 1409 if (stdi2dv_timings(sd, &stdi, timings)) {
1410 /*
1411 * The STDI block may measure wrong values, especially
1412 * for lcvs and lcf. If the driver can not find any
1413 * valid timing, the STDI block is restarted to measure
1414 * the video timings again. The function will return an
1415 * error, but the restart of STDI will generate a new
1416 * STDI interrupt and the format detection process will
1417 * restart.
1418 */
1419 if (state->restart_stdi_once) {
1420 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
1421 /* TODO restart STDI for Sync Channel 2 */
1422 /* enter one-shot mode */
1423 cp_write_and_or(sd, 0x86, 0xf9, 0x00);
1424 /* trigger STDI restart */
1425 cp_write_and_or(sd, 0x86, 0xf9, 0x04);
1426 /* reset to continuous mode */
1427 cp_write_and_or(sd, 0x86, 0xf9, 0x02);
1428 state->restart_stdi_once = false;
1429 return -ENOLINK;
1430 }
1401 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); 1431 v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
1402 return -ERANGE; 1432 return -ERANGE;
1403 } 1433 }
1434 state->restart_stdi_once = true;
1404 } 1435 }
1436found:
1405 1437
1406 if (debug > 1) 1438 if (debug > 1)
1407 v4l2_print_dv_timings(sd->name, "adv7842_query_dv_timings: ", 1439 v4l2_print_dv_timings(sd->name, "adv7842_query_dv_timings:",
1408 timings, true); 1440 timings, true);
1409 return 0; 1441 return 0;
1410} 1442}
1411 1443
@@ -2804,6 +2836,7 @@ static int adv7842_probe(struct i2c_client *client,
2804 state->mode = pdata->mode; 2836 state->mode = pdata->mode;
2805 2837
2806 state->hdmi_port_a = pdata->input == ADV7842_SELECT_HDMI_PORT_A; 2838 state->hdmi_port_a = pdata->input == ADV7842_SELECT_HDMI_PORT_A;
2839 state->restart_stdi_once = true;
2807 2840
2808 /* i2c access to adv7842? */ 2841 /* i2c access to adv7842? */
2809 rev = adv_smbus_read_byte_data_check(client, 0xea, false) << 8 | 2842 rev = adv_smbus_read_byte_data_check(client, 0xea, false) << 8 |