Commit 6519c3d7 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] adv7604: Don't ignore pad number in subdev DV timings pad operations

The dv_timings_cap() and enum_dv_timings() pad operations take a pad
number as an input argument and return the DV timings capabilities and
list of supported DV timings for that pad.

Commit bd3e275f ("[media] media: i2c: adv7604: Use v4l2-dv-timings
helpers") broke this as it started ignoring the pad number, always
returning the information associated with the currently selected input.
Fix it.

Fixes: bd3e275f ("[media] media: i2c: adv7604: Use v4l2-dv-timings helpers")
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Cc: <stable@vger.kernel.org>      # for v4.6
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 1ca830b1
...@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap adv76xx_timings_cap_digital = { ...@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap adv76xx_timings_cap_digital = {
V4L2_DV_BT_CAP_CUSTOM) V4L2_DV_BT_CAP_CUSTOM)
}; };
static inline const struct v4l2_dv_timings_cap * /*
adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd) * Return the DV timings capabilities for the requested sink pad. As a special
* case, pad value -1 returns the capabilities for the currently selected input.
*/
static const struct v4l2_dv_timings_cap *
adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd, int pad)
{ {
return is_digital_input(sd) ? &adv76xx_timings_cap_digital : if (pad == -1) {
&adv7604_timings_cap_analog; struct adv76xx_state *state = to_state(sd);
pad = state->selected_input;
}
switch (pad) {
case ADV76XX_PAD_HDMI_PORT_A:
case ADV7604_PAD_HDMI_PORT_B:
case ADV7604_PAD_HDMI_PORT_C:
case ADV7604_PAD_HDMI_PORT_D:
return &adv76xx_timings_cap_digital;
case ADV7604_PAD_VGA_RGB:
case ADV7604_PAD_VGA_COMP:
default:
return &adv7604_timings_cap_analog;
}
} }
...@@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, ...@@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt; const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i], if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i],
adv76xx_get_dv_timings_cap(sd), adv76xx_get_dv_timings_cap(sd, -1),
adv76xx_check_dv_timings, NULL)) adv76xx_check_dv_timings, NULL))
continue; continue;
if (vtotal(bt) != stdi->lcf + 1) if (vtotal(bt) != stdi->lcf + 1)
...@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd, ...@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd,
return -EINVAL; return -EINVAL;
return v4l2_enum_dv_timings_cap(timings, return v4l2_enum_dv_timings_cap(timings,
adv76xx_get_dv_timings_cap(sd), adv76xx_check_dv_timings, NULL); adv76xx_get_dv_timings_cap(sd, timings->pad),
adv76xx_check_dv_timings, NULL);
} }
static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd, static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
struct v4l2_dv_timings_cap *cap) struct v4l2_dv_timings_cap *cap)
{ {
struct adv76xx_state *state = to_state(sd); struct adv76xx_state *state = to_state(sd);
unsigned int pad = cap->pad;
if (cap->pad >= state->source_pad) if (cap->pad >= state->source_pad)
return -EINVAL; return -EINVAL;
*cap = *adv76xx_get_dv_timings_cap(sd); *cap = *adv76xx_get_dv_timings_cap(sd, pad);
cap->pad = pad;
return 0; return 0;
} }
...@@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd, ...@@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
struct v4l2_dv_timings *timings) struct v4l2_dv_timings *timings)
{ {
v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd), v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd, -1),
is_digital_input(sd) ? 250000 : 1000000, is_digital_input(sd) ? 250000 : 1000000,
adv76xx_check_dv_timings, NULL); adv76xx_check_dv_timings, NULL);
} }
static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd) 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,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
bt = &timings->bt; bt = &timings->bt;
if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd), if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd, -1),
adv76xx_check_dv_timings, NULL)) adv76xx_check_dv_timings, NULL))
return -ERANGE; return -ERANGE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment