From 40aaca6ed160e67e518c512908cf49efb4cbed8b Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Wed, 29 Apr 2020 16:45:02 +0100 Subject: [PATCH] media: bcm2835-unicam: Add support for VIDIOC_[S|G]_SELECTION Sensors are now reflecting cropping and scaling parameters through the selection API, therefore Unicam needs to forward the requests through to the subdev. Signed-off-by: Dave Stevenson --- .../media/platform/bcm2835/bcm2835-unicam.c | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) --- a/drivers/media/platform/bcm2835/bcm2835-unicam.c +++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c @@ -1898,6 +1898,39 @@ static int unicam_g_edid(struct file *fi return v4l2_subdev_call(dev->sensor, pad, get_edid, edid); } +static int unicam_s_selection(struct file *file, void *priv, + struct v4l2_selection *sel) +{ + struct unicam_node *node = video_drvdata(file); + struct unicam_device *dev = node->dev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + + return v4l2_subdev_call(dev->sensor, pad, set_selection, NULL, &sdsel); +} + +static int unicam_g_selection(struct file *file, void *priv, + struct v4l2_selection *sel) +{ + struct unicam_node *node = video_drvdata(file); + struct unicam_device *dev = node->dev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + }; + int ret; + + ret = v4l2_subdev_call(dev->sensor, pad, get_selection, NULL, &sdsel); + if (!ret) + sel->r = sdsel.r; + + return ret; +} + static int unicam_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize) { @@ -2218,6 +2251,9 @@ static const struct v4l2_ioctl_ops unica .vidioc_enum_framesizes = unicam_enum_framesizes, .vidioc_enum_frameintervals = unicam_enum_frameintervals, + .vidioc_g_selection = unicam_g_selection, + .vidioc_s_selection = unicam_s_selection, + .vidioc_g_parm = unicam_g_parm, .vidioc_s_parm = unicam_s_parm, @@ -2446,6 +2482,14 @@ static int register_node(struct unicam_d !v4l2_subdev_has_op(unicam->sensor, pad, enum_frame_size)) v4l2_disable_ioctl(&node->video_dev, VIDIOC_ENUM_FRAMESIZES); + if (node->pad_id == METADATA_PAD || + !v4l2_subdev_has_op(unicam->sensor, pad, set_selection)) + v4l2_disable_ioctl(&node->video_dev, VIDIOC_S_SELECTION); + + if (node->pad_id == METADATA_PAD || + !v4l2_subdev_has_op(unicam->sensor, pad, get_selection)) + v4l2_disable_ioctl(&node->video_dev, VIDIOC_G_SELECTION); + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) { unicam_err(unicam, "Unable to register video device.\n");