aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/i2c/adv7604.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index beb2841ceae5..3f1ab4986cfc 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap adv76xx_timings_cap_digital = {
779 V4L2_DV_BT_CAP_CUSTOM) 779 V4L2_DV_BT_CAP_CUSTOM)
780}; 780};
781 781
782static inline const struct v4l2_dv_timings_cap * 782/*
783adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd) 783 * Return the DV timings capabilities for the requested sink pad. As a special
784 * case, pad value -1 returns the capabilities for the currently selected input.
785 */
786static const struct v4l2_dv_timings_cap *
787adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd, int pad)
784{ 788{
785 return is_digital_input(sd) ? &adv76xx_timings_cap_digital : 789 if (pad == -1) {
786 &adv7604_timings_cap_analog; 790 struct adv76xx_state *state = to_state(sd);
791
792 pad = state->selected_input;
793 }
794
795 switch (pad) {
796 case ADV76XX_PAD_HDMI_PORT_A:
797 case ADV7604_PAD_HDMI_PORT_B:
798 case ADV7604_PAD_HDMI_PORT_C:
799 case ADV7604_PAD_HDMI_PORT_D:
800 return &adv76xx_timings_cap_digital;
801
802 case ADV7604_PAD_VGA_RGB:
803 case ADV7604_PAD_VGA_COMP:
804 default:
805 return &adv7604_timings_cap_analog;
806 }
787} 807}
788 808
789 809
@@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
1329 const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt; 1349 const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
1330 1350
1331 if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i], 1351 if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i],
1332 adv76xx_get_dv_timings_cap(sd), 1352 adv76xx_get_dv_timings_cap(sd, -1),
1333 adv76xx_check_dv_timings, NULL)) 1353 adv76xx_check_dv_timings, NULL))
1334 continue; 1354 continue;
1335 if (vtotal(bt) != stdi->lcf + 1) 1355 if (vtotal(bt) != stdi->lcf + 1)
@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd,
1430 return -EINVAL; 1450 return -EINVAL;
1431 1451
1432 return v4l2_enum_dv_timings_cap(timings, 1452 return v4l2_enum_dv_timings_cap(timings,
1433 adv76xx_get_dv_timings_cap(sd), adv76xx_check_dv_timings, NULL); 1453 adv76xx_get_dv_timings_cap(sd, timings->pad),
1454 adv76xx_check_dv_timings, NULL);
1434} 1455}
1435 1456
1436static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd, 1457static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
1437 struct v4l2_dv_timings_cap *cap) 1458 struct v4l2_dv_timings_cap *cap)
1438{ 1459{
1439 struct adv76xx_state *state = to_state(sd); 1460 struct adv76xx_state *state = to_state(sd);
1461 unsigned int pad = cap->pad;
1440 1462
1441 if (cap->pad >= state->source_pad) 1463 if (cap->pad >= state->source_pad)
1442 return -EINVAL; 1464 return -EINVAL;
1443 1465
1444 *cap = *adv76xx_get_dv_timings_cap(sd); 1466 *cap = *adv76xx_get_dv_timings_cap(sd, pad);
1467 cap->pad = pad;
1468
1445 return 0; 1469 return 0;
1446} 1470}
1447 1471
@@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
1450static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, 1474static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
1451 struct v4l2_dv_timings *timings) 1475 struct v4l2_dv_timings *timings)
1452{ 1476{
1453 v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd), 1477 v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd, -1),
1454 is_digital_input(sd) ? 250000 : 1000000, 1478 is_digital_input(sd) ? 250000 : 1000000,
1455 adv76xx_check_dv_timings, NULL); 1479 adv76xx_check_dv_timings, NULL);
1456} 1480}
1457 1481
1458static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd) 1482static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
@@ -1620,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
1620 1644
1621 bt = &timings->bt; 1645 bt = &timings->bt;
1622 1646
1623 if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd), 1647 if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd, -1),
1624 adv76xx_check_dv_timings, NULL)) 1648 adv76xx_check_dv_timings, NULL))
1625 return -ERANGE; 1649 return -ERANGE;
1626 1650