aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0838-staging-vc04_services-isp-Fixup-g-s_selection-implem.patch
blob: fd24c87bc326e6c99b3d530ff221f6edce481deb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 7ec008222fcb4682fa2cfdbb62e657bf98950ec5 Mon Sep 17 00:00:00 2001
From: Naushir Patuck <naush@raspberrypi.com>
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 <naush@raspberrypi.com>
---
 .../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;
 	}