summaryrefslogtreecommitdiff
path: root/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/rockchip/rkcif/rkcif-interface.c')
-rw-r--r--drivers/media/platform/rockchip/rkcif/rkcif-interface.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
index 0fe9410e23ed..523103872b7a 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
@@ -157,15 +157,41 @@ static int rkcif_interface_set_routing(struct v4l2_subdev *sd,
if (ret)
return ret;
+ for (unsigned int i = 0; i < routing->num_routes; i++) {
+ const struct v4l2_subdev_route *route = &routing->routes[i];
+
+ if (route->source_stream >= RKCIF_ID_MAX)
+ return -EINVAL;
+ }
+
ret = v4l2_subdev_set_routing(sd, state, routing);
return ret;
}
+static int rkcif_interface_apply_crop(struct rkcif_stream *stream,
+ struct v4l2_subdev_state *state)
+{
+ struct rkcif_interface *interface = stream->interface;
+ struct v4l2_rect *crop;
+
+ crop = v4l2_subdev_state_get_crop(state, RKCIF_IF_PAD_SRC, stream->id);
+ if (!crop)
+ return -EINVAL;
+
+ if (interface->set_crop)
+ interface->set_crop(stream, crop->left, crop->top);
+
+ return 0;
+}
+
static int rkcif_interface_enable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state,
u32 pad, u64 streams_mask)
{
+ struct rkcif_interface *interface = to_rkcif_interface(sd);
+ struct rkcif_stream *stream;
+ struct v4l2_subdev_route *route;
struct v4l2_subdev *remote_sd;
struct media_pad *remote_pad;
u64 mask;
@@ -174,6 +200,17 @@ static int rkcif_interface_enable_streams(struct v4l2_subdev *sd,
media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]);
remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+ /* DVP has one crop setting for all IDs */
+ if (interface->type == RKCIF_IF_DVP) {
+ stream = &interface->streams[RKCIF_ID0];
+ rkcif_interface_apply_crop(stream, state);
+ } else {
+ for_each_active_route(&state->routing, route) {
+ stream = &interface->streams[route->sink_stream];
+ rkcif_interface_apply_crop(stream, state);
+ }
+ }
+
mask = v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK,
RKCIF_IF_PAD_SRC, &streams_mask);