Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c41e690 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[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>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 81ea4829
Loading
Loading
Loading
Loading
+35 −11
Original line number Diff line number Diff line
@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap adv76xx_timings_cap_digital = {
			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 :
				      &adv7604_timings_cap_analog;
	if (pad == -1) {
		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,
		const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;

		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))
			continue;
		if (vtotal(bt) != stdi->lcf + 1)
@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd,
		return -EINVAL;

	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,
			struct v4l2_dv_timings_cap *cap)
{
	struct adv76xx_state *state = to_state(sd);
	unsigned int pad = cap->pad;

	if (cap->pad >= state->source_pad)
		return -EINVAL;

	*cap = *adv76xx_get_dv_timings_cap(sd);
	*cap = *adv76xx_get_dv_timings_cap(sd, pad);
	cap->pad = pad;

	return 0;
}

@@ -1450,7 +1474,7 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
		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,
				 adv76xx_check_dv_timings, NULL);
}
@@ -1620,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,

	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))
		return -ERANGE;