Commit 6b456240 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Hans Verkuil
Browse files

media: v4l2-subdev: Store frame interval in subdev state



Subdev states store all standard pad configuration data, except for
frame intervals. Fix it by adding interval fields in the
v4l2_subdev_pad_config and v4l2_subdev_stream_config structures, with
corresponding accessor functions and a helper function to implement the
.get_frame_interval() operation.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent 805d4311
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -1652,6 +1652,42 @@ __v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,
}
EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_compose);

struct v4l2_fract *
__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state,
				 unsigned int pad, u32 stream)
{
	struct v4l2_subdev_stream_configs *stream_configs;
	unsigned int i;

	if (WARN_ON(!state))
		return NULL;

	lockdep_assert_held(state->lock);

	if (state->pads) {
		if (stream)
			return NULL;

		if (pad >= state->sd->entity.num_pads)
			return NULL;

		return &state->pads[pad].interval;
	}

	lockdep_assert_held(state->lock);

	stream_configs = &state->stream_configs;

	for (i = 0; i < stream_configs->num_configs; ++i) {
		if (stream_configs->configs[i].pad == pad &&
		    stream_configs->configs[i].stream == stream)
			return &stream_configs->configs[i].interval;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(__v4l2_subdev_state_get_interval);

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)

static int
@@ -1718,6 +1754,22 @@ int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,
}
EXPORT_SYMBOL_GPL(v4l2_subdev_get_fmt);

int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_frame_interval *fi)
{
	struct v4l2_fract *interval;

	interval = v4l2_subdev_state_get_interval(state, fi->pad, fi->stream);
	if (!interval)
		return -EINVAL;

	fi->interval = *interval;

	return 0;
}
EXPORT_SYMBOL_GPL(v4l2_subdev_get_frame_interval);

int v4l2_subdev_set_routing(struct v4l2_subdev *sd,
			    struct v4l2_subdev_state *state,
			    const struct v4l2_subdev_krouting *routing)
+43 −0
Original line number Diff line number Diff line
@@ -681,11 +681,13 @@ struct v4l2_subdev_ir_ops {
 * @format: &struct v4l2_mbus_framefmt
 * @crop: &struct v4l2_rect to be used for crop
 * @compose: &struct v4l2_rect to be used for compose
 * @interval: frame interval
 */
struct v4l2_subdev_pad_config {
	struct v4l2_mbus_framefmt format;
	struct v4l2_rect crop;
	struct v4l2_rect compose;
	struct v4l2_fract interval;
};

/**
@@ -697,6 +699,7 @@ struct v4l2_subdev_pad_config {
 * @fmt: &struct v4l2_mbus_framefmt
 * @crop: &struct v4l2_rect to be used for crop
 * @compose: &struct v4l2_rect to be used for compose
 * @interval: frame interval
 *
 * This structure stores configuration for a stream.
 */
@@ -708,6 +711,7 @@ struct v4l2_subdev_stream_config {
	struct v4l2_mbus_framefmt fmt;
	struct v4l2_rect crop;
	struct v4l2_rect compose;
	struct v4l2_fract interval;
};

/**
@@ -1392,6 +1396,27 @@ struct v4l2_rect *
__v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,
				unsigned int pad, u32 stream);

/**
 * v4l2_subdev_state_get_interval() - Get pointer to a stream frame interval
 * @state: subdevice state
 * @pad: pad id
 * @...: stream id (optional argument)
 *
 * This returns a pointer to the frame interval for the given pad + stream in
 * the subdev state.
 *
 * For stream-unaware drivers the frame interval for the corresponding pad is
 * returned. If the pad does not exist, NULL is returned.
 */
#define v4l2_subdev_state_get_interval(state, pad, ...)			\
	__v4l2_subdev_state_gen_call(interval, ##__VA_ARGS__, , _pad)	\
		(state, pad, ##__VA_ARGS__)
#define __v4l2_subdev_state_get_interval_pad(state, pad)	\
	__v4l2_subdev_state_get_interval(state, pad, 0)
struct v4l2_fract *
__v4l2_subdev_state_get_interval(struct v4l2_subdev_state *state,
				 unsigned int pad, u32 stream);

#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)

/**
@@ -1411,6 +1436,24 @@ __v4l2_subdev_state_get_compose(struct v4l2_subdev_state *state,
int v4l2_subdev_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *state,
			struct v4l2_subdev_format *format);

/**
 * v4l2_subdev_get_frame_interval() - Fill frame interval based on state
 * @sd: subdevice
 * @state: subdevice state
 * @fi: pointer to &struct v4l2_subdev_frame_interval
 *
 * Fill @fi->interval field based on the information in the @fi struct.
 *
 * This function can be used by the subdev drivers which support active state to
 * implement v4l2_subdev_pad_ops.get_frame_interval if the subdev driver does
 * not need to do anything special in their get_frame_interval op.
 *
 * Returns 0 on success, error value otherwise.
 */
int v4l2_subdev_get_frame_interval(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_frame_interval *fi);

/**
 * v4l2_subdev_set_routing() - Set given routing to subdev state
 * @sd: The subdevice