diff options
-rw-r--r-- | drivers/media/i2c/adv7604.c | 46 |
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 | ||
782 | static inline const struct v4l2_dv_timings_cap * | 782 | /* |
783 | adv76xx_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 | */ | ||
786 | static const struct v4l2_dv_timings_cap * | ||
787 | adv76xx_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 | ||
1436 | static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd, | 1457 | static 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, | |||
1450 | static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, | 1474 | static 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 | ||
1458 | static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd) | 1482 | static 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 | ||