From 7ec008222fcb4682fa2cfdbb62e657bf98950ec5 Mon Sep 17 00:00:00 2001 From: Naushir Patuck Date: Tue, 19 May 2020 15:56:47 +0100 Subject: [PATCH] staging: vc04_services: isp: Fixup g/s_selection implementation Add V4L2_SEL_TGT_CROP_DEFAULT and V4L2_SEL_TGT_CROP_BOUND targets. Disable the appropriate ioctls for the meta capture nodes - this now passes v4l2-compliance tests. Signed-off-by: Naushir Patuck --- .../bcm2835-isp/bcm2835-v4l2-isp.c | 84 ++++++++++++------- 1 file changed, 55 insertions(+), 29 deletions(-) --- a/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c +++ b/drivers/staging/vc04_services/bcm2835-isp/bcm2835-v4l2-isp.c @@ -1006,15 +1006,32 @@ static int bcm2835_isp_node_s_selection( if (!s->r.width || !s->r.height) return -EINVAL; - /* Adjust the crop window if goes outside the frame dimensions. */ - s->r.left = min((unsigned int)max(s->r.left, 0), - node->q_data.width - MIN_DIM); - s->r.top = min((unsigned int)max(s->r.top, 0), - node->q_data.height - MIN_DIM); - s->r.width = max(min(s->r.width, node->q_data.width - s->r.left), - MIN_DIM); - s->r.height = max(min(s->r.height, node->q_data.height - s->r.top), - MIN_DIM); + /* We can only set crop on the input. */ + switch (s->target) { + case V4L2_SEL_TGT_CROP: + /* + * Adjust the crop window if it goes outside of the frame + * dimensions. + */ + s->r.left = min((unsigned int)max(s->r.left, 0), + node->q_data.width - MIN_DIM); + s->r.top = min((unsigned int)max(s->r.top, 0), + node->q_data.height - MIN_DIM); + s->r.width = max(min(s->r.width, + node->q_data.width - s->r.left), MIN_DIM); + s->r.height = max(min(s->r.height, + node->q_data.height - s->r.top), MIN_DIM); + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + /* Default (i.e. no) crop window. */ + s->r.left = 0; + s->r.top = 0; + s->r.width = node->q_data.width; + s->r.height = node->q_data.height; + break; + default: + return -EINVAL; + } crop.rect.x = s->r.left; crop.rect.y = s->r.top; @@ -1029,33 +1046,40 @@ static int bcm2835_isp_node_s_selection( static int bcm2835_isp_node_g_selection(struct file *file, void *fh, struct v4l2_selection *s) { + struct mmal_parameter_crop crop; struct bcm2835_isp_node *node = video_drvdata(file); - struct bcm2835_isp_dev *dev = node_get_dev(node); struct vchiq_mmal_port *port = get_port_data(node); - struct mmal_parameter_crop crop; + struct bcm2835_isp_dev *dev = node_get_dev(node); u32 crop_size = sizeof(crop); int ret; - /* This return value is required for V4L2 compliance. */ - if (node_is_stats(node)) - return -ENOTTY; - /* We can only return out an input crop. */ - if (s->target != V4L2_SEL_TGT_CROP) - return -EINVAL; - - ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port, - MMAL_PARAMETER_CROP, - &crop, &crop_size); - if (!ret) - return -EINVAL; - - s->r.left = crop.rect.x; - s->r.top = crop.rect.y; - s->r.width = crop.rect.width; - s->r.height = crop.rect.height; + switch (s->target) { + case V4L2_SEL_TGT_CROP: + ret = vchiq_mmal_port_parameter_get(dev->mmal_instance, port, + MMAL_PARAMETER_CROP, + &crop, &crop_size); + if (!ret) { + s->r.left = crop.rect.x; + s->r.top = crop.rect.y; + s->r.width = crop.rect.width; + s->r.height = crop.rect.height; + } + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + /* Default (i.e. no) crop window. */ + s->r.left = 0; + s->r.top = 0; + s->r.width = node->q_data.width; + s->r.height = node->q_data.height; + ret = 0; + break; + default: + ret = -EINVAL; + } - return 0; + return ret; } static int bcm3285_isp_subscribe_event(struct v4l2_fh *fh, @@ -1218,6 +1242,8 @@ static int register_node(struct bcm2835_ node->vfl_dir = VFL_DIR_RX; node->name = "stats"; v4l2_disable_ioctl(&node->vfd, VIDIOC_S_CTRL); + v4l2_disable_ioctl(&node->vfd, VIDIOC_S_SELECTION); + v4l2_disable_ioctl(&node->vfd, VIDIOC_G_SELECTION); break; }