Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] v4l2: remove g/s_crop from video ops

Replace all calls to g/s_crop by calls to the get/set_selection pad ops.

Remove the old g/s_crop video ops since they are now no longer used.

The cropcap video op is now only used to pass pixelaspect information,
and is only needed if the pixelaspect is not 1:1.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
10d5509c 65d9e14a

+751 -680
+17 -11
drivers/media/i2c/ak881x.c
··· 124 124 return 0; 125 125 } 126 126 127 - static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 127 + static int ak881x_get_selection(struct v4l2_subdev *sd, 128 + struct v4l2_subdev_pad_config *cfg, 129 + struct v4l2_subdev_selection *sel) 128 130 { 129 131 struct i2c_client *client = v4l2_get_subdevdata(sd); 130 132 struct ak881x *ak881x = to_ak881x(client); 131 133 132 - a->bounds.left = 0; 133 - a->bounds.top = 0; 134 - a->bounds.width = 720; 135 - a->bounds.height = ak881x->lines; 136 - a->defrect = a->bounds; 137 - a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 138 - a->pixelaspect.numerator = 1; 139 - a->pixelaspect.denominator = 1; 134 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 135 + return -EINVAL; 140 136 141 - return 0; 137 + switch (sel->target) { 138 + case V4L2_SEL_TGT_CROP_BOUNDS: 139 + case V4L2_SEL_TGT_CROP_DEFAULT: 140 + sel->r.left = 0; 141 + sel->r.top = 0; 142 + sel->r.width = 720; 143 + sel->r.height = ak881x->lines; 144 + return 0; 145 + default: 146 + return -EINVAL; 147 + } 142 148 } 143 149 144 150 static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) ··· 213 207 }; 214 208 215 209 static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = { 216 - .cropcap = ak881x_cropcap, 217 210 .s_std_output = ak881x_s_std_output, 218 211 .s_stream = ak881x_s_stream, 219 212 }; 220 213 221 214 static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = { 222 215 .enum_mbus_code = ak881x_enum_mbus_code, 216 + .get_selection = ak881x_get_selection, 223 217 .set_fmt = ak881x_fill_fmt, 224 218 .get_fmt = ak881x_fill_fmt, 225 219 };
+18 -24
drivers/media/i2c/soc_camera/imx074.c
··· 209 209 return 0; 210 210 } 211 211 212 - static int imx074_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 212 + static int imx074_get_selection(struct v4l2_subdev *sd, 213 + struct v4l2_subdev_pad_config *cfg, 214 + struct v4l2_subdev_selection *sel) 213 215 { 214 - struct v4l2_rect *rect = &a->c; 216 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 217 + return -EINVAL; 215 218 216 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 217 - rect->top = 0; 218 - rect->left = 0; 219 - rect->width = IMX074_WIDTH; 220 - rect->height = IMX074_HEIGHT; 219 + sel->r.left = 0; 220 + sel->r.top = 0; 221 + sel->r.width = IMX074_WIDTH; 222 + sel->r.height = IMX074_HEIGHT; 221 223 222 - return 0; 223 - } 224 - 225 - static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 226 - { 227 - a->bounds.left = 0; 228 - a->bounds.top = 0; 229 - a->bounds.width = IMX074_WIDTH; 230 - a->bounds.height = IMX074_HEIGHT; 231 - a->defrect = a->bounds; 232 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 233 - a->pixelaspect.numerator = 1; 234 - a->pixelaspect.denominator = 1; 235 - 236 - return 0; 224 + switch (sel->target) { 225 + case V4L2_SEL_TGT_CROP_BOUNDS: 226 + case V4L2_SEL_TGT_CROP_DEFAULT: 227 + case V4L2_SEL_TGT_CROP: 228 + return 0; 229 + default: 230 + return -EINVAL; 231 + } 237 232 } 238 233 239 234 static int imx074_enum_mbus_code(struct v4l2_subdev *sd, ··· 273 278 274 279 static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { 275 280 .s_stream = imx074_s_stream, 276 - .g_crop = imx074_g_crop, 277 - .cropcap = imx074_cropcap, 278 281 .g_mbus_config = imx074_g_mbus_config, 279 282 }; 280 283 ··· 282 289 283 290 static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = { 284 291 .enum_mbus_code = imx074_enum_mbus_code, 292 + .get_selection = imx074_get_selection, 285 293 .get_fmt = imx074_get_fmt, 286 294 .set_fmt = imx074_set_fmt, 287 295 };
+38 -32
drivers/media/i2c/soc_camera/mt9m001.c
··· 171 171 return 0; 172 172 } 173 173 174 - static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 174 + static int mt9m001_set_selection(struct v4l2_subdev *sd, 175 + struct v4l2_subdev_pad_config *cfg, 176 + struct v4l2_subdev_selection *sel) 175 177 { 176 178 struct i2c_client *client = v4l2_get_subdevdata(sd); 177 179 struct mt9m001 *mt9m001 = to_mt9m001(client); 178 - struct v4l2_rect rect = a->c; 179 - int ret; 180 + struct v4l2_rect rect = sel->r; 180 181 const u16 hblank = 9, vblank = 25; 182 + int ret; 183 + 184 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 185 + sel->target != V4L2_SEL_TGT_CROP) 186 + return -EINVAL; 181 187 182 188 if (mt9m001->fmts == mt9m001_colour_fmts) 183 189 /* ··· 231 225 return ret; 232 226 } 233 227 234 - static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 228 + static int mt9m001_get_selection(struct v4l2_subdev *sd, 229 + struct v4l2_subdev_pad_config *cfg, 230 + struct v4l2_subdev_selection *sel) 235 231 { 236 232 struct i2c_client *client = v4l2_get_subdevdata(sd); 237 233 struct mt9m001 *mt9m001 = to_mt9m001(client); 238 234 239 - a->c = mt9m001->rect; 240 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 235 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 236 + return -EINVAL; 241 237 242 - return 0; 243 - } 244 - 245 - static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 246 - { 247 - a->bounds.left = MT9M001_COLUMN_SKIP; 248 - a->bounds.top = MT9M001_ROW_SKIP; 249 - a->bounds.width = MT9M001_MAX_WIDTH; 250 - a->bounds.height = MT9M001_MAX_HEIGHT; 251 - a->defrect = a->bounds; 252 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 253 - a->pixelaspect.numerator = 1; 254 - a->pixelaspect.denominator = 1; 255 - 256 - return 0; 238 + switch (sel->target) { 239 + case V4L2_SEL_TGT_CROP_BOUNDS: 240 + case V4L2_SEL_TGT_CROP_DEFAULT: 241 + sel->r.left = MT9M001_COLUMN_SKIP; 242 + sel->r.top = MT9M001_ROW_SKIP; 243 + sel->r.width = MT9M001_MAX_WIDTH; 244 + sel->r.height = MT9M001_MAX_HEIGHT; 245 + return 0; 246 + case V4L2_SEL_TGT_CROP: 247 + sel->r = mt9m001->rect; 248 + return 0; 249 + default: 250 + return -EINVAL; 251 + } 257 252 } 258 253 259 254 static int mt9m001_get_fmt(struct v4l2_subdev *sd, ··· 282 275 { 283 276 struct i2c_client *client = v4l2_get_subdevdata(sd); 284 277 struct mt9m001 *mt9m001 = to_mt9m001(client); 285 - struct v4l2_crop a = { 286 - .c = { 287 - .left = mt9m001->rect.left, 288 - .top = mt9m001->rect.top, 289 - .width = mf->width, 290 - .height = mf->height, 291 - }, 278 + struct v4l2_subdev_selection sel = { 279 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 280 + .target = V4L2_SEL_TGT_CROP, 281 + .r.left = mt9m001->rect.left, 282 + .r.top = mt9m001->rect.top, 283 + .r.width = mf->width, 284 + .r.height = mf->height, 292 285 }; 293 286 int ret; 294 287 295 288 /* No support for scaling so far, just crop. TODO: use skipping */ 296 - ret = mt9m001_s_crop(sd, &a); 289 + ret = mt9m001_set_selection(sd, NULL, &sel); 297 290 if (!ret) { 298 291 mf->width = mt9m001->rect.width; 299 292 mf->height = mt9m001->rect.height; ··· 632 625 633 626 static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { 634 627 .s_stream = mt9m001_s_stream, 635 - .s_crop = mt9m001_s_crop, 636 - .g_crop = mt9m001_g_crop, 637 - .cropcap = mt9m001_cropcap, 638 628 .g_mbus_config = mt9m001_g_mbus_config, 639 629 .s_mbus_config = mt9m001_s_mbus_config, 640 630 }; ··· 642 638 643 639 static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { 644 640 .enum_mbus_code = mt9m001_enum_mbus_code, 641 + .get_selection = mt9m001_get_selection, 642 + .set_selection = mt9m001_set_selection, 645 643 .get_fmt = mt9m001_get_fmt, 646 644 .set_fmt = mt9m001_set_fmt, 647 645 };
+30 -27
drivers/media/i2c/soc_camera/mt9m111.c
··· 383 383 return ret; 384 384 } 385 385 386 - static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 386 + static int mt9m111_set_selection(struct v4l2_subdev *sd, 387 + struct v4l2_subdev_pad_config *cfg, 388 + struct v4l2_subdev_selection *sel) 387 389 { 388 - struct v4l2_rect rect = a->c; 389 - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); 390 + struct i2c_client *client = v4l2_get_subdevdata(sd); 391 + struct mt9m111 *mt9m111 = to_mt9m111(client); 392 + struct v4l2_rect rect = sel->r; 390 393 int width, height; 391 394 int ret; 392 395 393 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 396 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 397 + sel->target != V4L2_SEL_TGT_CROP) 394 398 return -EINVAL; 395 399 396 400 if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || ··· 425 421 return ret; 426 422 } 427 423 428 - static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 424 + static int mt9m111_get_selection(struct v4l2_subdev *sd, 425 + struct v4l2_subdev_pad_config *cfg, 426 + struct v4l2_subdev_selection *sel) 429 427 { 430 - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); 428 + struct i2c_client *client = v4l2_get_subdevdata(sd); 429 + struct mt9m111 *mt9m111 = to_mt9m111(client); 431 430 432 - a->c = mt9m111->rect; 433 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 434 - 435 - return 0; 436 - } 437 - 438 - static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 439 - { 440 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 431 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 441 432 return -EINVAL; 442 433 443 - a->bounds.left = MT9M111_MIN_DARK_COLS; 444 - a->bounds.top = MT9M111_MIN_DARK_ROWS; 445 - a->bounds.width = MT9M111_MAX_WIDTH; 446 - a->bounds.height = MT9M111_MAX_HEIGHT; 447 - a->defrect = a->bounds; 448 - a->pixelaspect.numerator = 1; 449 - a->pixelaspect.denominator = 1; 450 - 451 - return 0; 434 + switch (sel->target) { 435 + case V4L2_SEL_TGT_CROP_BOUNDS: 436 + case V4L2_SEL_TGT_CROP_DEFAULT: 437 + sel->r.left = MT9M111_MIN_DARK_COLS; 438 + sel->r.top = MT9M111_MIN_DARK_ROWS; 439 + sel->r.width = MT9M111_MAX_WIDTH; 440 + sel->r.height = MT9M111_MAX_HEIGHT; 441 + return 0; 442 + case V4L2_SEL_TGT_CROP: 443 + sel->r = mt9m111->rect; 444 + return 0; 445 + default: 446 + return -EINVAL; 447 + } 452 448 } 453 449 454 450 static int mt9m111_get_fmt(struct v4l2_subdev *sd, ··· 871 867 } 872 868 873 869 static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { 874 - .s_crop = mt9m111_s_crop, 875 - .g_crop = mt9m111_g_crop, 876 - .cropcap = mt9m111_cropcap, 877 870 .g_mbus_config = mt9m111_g_mbus_config, 878 871 }; 879 872 880 873 static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { 881 874 .enum_mbus_code = mt9m111_enum_mbus_code, 875 + .get_selection = mt9m111_get_selection, 876 + .set_selection = mt9m111_set_selection, 882 877 .get_fmt = mt9m111_get_fmt, 883 878 .set_fmt = mt9m111_set_fmt, 884 879 };
+30 -24
drivers/media/i2c/soc_camera/mt9t031.c
··· 264 264 265 265 /* 266 266 * The caller provides a supported format, as guaranteed by 267 - * .set_fmt(FORMAT_TRY), soc_camera_s_crop() and soc_camera_cropcap() 267 + * .set_fmt(FORMAT_TRY), soc_camera_s_selection() and soc_camera_cropcap() 268 268 */ 269 269 if (ret >= 0) 270 270 ret = reg_write(client, MT9T031_COLUMN_START, rect->left); ··· 294 294 return ret < 0 ? ret : 0; 295 295 } 296 296 297 - static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 297 + static int mt9t031_set_selection(struct v4l2_subdev *sd, 298 + struct v4l2_subdev_pad_config *cfg, 299 + struct v4l2_subdev_selection *sel) 298 300 { 299 - struct v4l2_rect rect = a->c; 300 301 struct i2c_client *client = v4l2_get_subdevdata(sd); 301 302 struct mt9t031 *mt9t031 = to_mt9t031(client); 303 + struct v4l2_rect rect = sel->r; 304 + 305 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 306 + sel->target != V4L2_SEL_TGT_CROP) 307 + return -EINVAL; 302 308 303 309 rect.width = ALIGN(rect.width, 2); 304 310 rect.height = ALIGN(rect.height, 2); ··· 318 312 return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip); 319 313 } 320 314 321 - static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 315 + static int mt9t031_get_selection(struct v4l2_subdev *sd, 316 + struct v4l2_subdev_pad_config *cfg, 317 + struct v4l2_subdev_selection *sel) 322 318 { 323 319 struct i2c_client *client = v4l2_get_subdevdata(sd); 324 320 struct mt9t031 *mt9t031 = to_mt9t031(client); 325 321 326 - a->c = mt9t031->rect; 327 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 322 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 323 + return -EINVAL; 328 324 329 - return 0; 330 - } 331 - 332 - static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 333 - { 334 - a->bounds.left = MT9T031_COLUMN_SKIP; 335 - a->bounds.top = MT9T031_ROW_SKIP; 336 - a->bounds.width = MT9T031_MAX_WIDTH; 337 - a->bounds.height = MT9T031_MAX_HEIGHT; 338 - a->defrect = a->bounds; 339 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 340 - a->pixelaspect.numerator = 1; 341 - a->pixelaspect.denominator = 1; 342 - 343 - return 0; 325 + switch (sel->target) { 326 + case V4L2_SEL_TGT_CROP_BOUNDS: 327 + case V4L2_SEL_TGT_CROP_DEFAULT: 328 + sel->r.left = MT9T031_COLUMN_SKIP; 329 + sel->r.top = MT9T031_ROW_SKIP; 330 + sel->r.width = MT9T031_MAX_WIDTH; 331 + sel->r.height = MT9T031_MAX_HEIGHT; 332 + return 0; 333 + case V4L2_SEL_TGT_CROP: 334 + sel->r = mt9t031->rect; 335 + return 0; 336 + default: 337 + return -EINVAL; 338 + } 344 339 } 345 340 346 341 static int mt9t031_get_fmt(struct v4l2_subdev *sd, ··· 728 721 729 722 static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { 730 723 .s_stream = mt9t031_s_stream, 731 - .s_crop = mt9t031_s_crop, 732 - .g_crop = mt9t031_g_crop, 733 - .cropcap = mt9t031_cropcap, 734 724 .g_mbus_config = mt9t031_g_mbus_config, 735 725 .s_mbus_config = mt9t031_s_mbus_config, 736 726 }; ··· 738 734 739 735 static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = { 740 736 .enum_mbus_code = mt9t031_enum_mbus_code, 737 + .get_selection = mt9t031_get_selection, 738 + .set_selection = mt9t031_set_selection, 741 739 .get_fmt = mt9t031_get_fmt, 742 740 .set_fmt = mt9t031_set_fmt, 743 741 };
+34 -26
drivers/media/i2c/soc_camera/mt9t112.c
··· 867 867 return 0; 868 868 } 869 869 870 - static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 871 - { 872 - a->bounds.left = 0; 873 - a->bounds.top = 0; 874 - a->bounds.width = MAX_WIDTH; 875 - a->bounds.height = MAX_HEIGHT; 876 - a->defrect.left = 0; 877 - a->defrect.top = 0; 878 - a->defrect.width = VGA_WIDTH; 879 - a->defrect.height = VGA_HEIGHT; 880 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 881 - a->pixelaspect.numerator = 1; 882 - a->pixelaspect.denominator = 1; 883 - 884 - return 0; 885 - } 886 - 887 - static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 870 + static int mt9t112_get_selection(struct v4l2_subdev *sd, 871 + struct v4l2_subdev_pad_config *cfg, 872 + struct v4l2_subdev_selection *sel) 888 873 { 889 874 struct i2c_client *client = v4l2_get_subdevdata(sd); 890 875 struct mt9t112_priv *priv = to_mt9t112(client); 891 876 892 - a->c = priv->frame; 893 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 877 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 878 + return -EINVAL; 894 879 895 - return 0; 880 + switch (sel->target) { 881 + case V4L2_SEL_TGT_CROP_BOUNDS: 882 + sel->r.left = 0; 883 + sel->r.top = 0; 884 + sel->r.width = MAX_WIDTH; 885 + sel->r.height = MAX_HEIGHT; 886 + return 0; 887 + case V4L2_SEL_TGT_CROP_DEFAULT: 888 + sel->r.left = 0; 889 + sel->r.top = 0; 890 + sel->r.width = VGA_WIDTH; 891 + sel->r.height = VGA_HEIGHT; 892 + return 0; 893 + case V4L2_SEL_TGT_CROP: 894 + sel->r = priv->frame; 895 + return 0; 896 + default: 897 + return -EINVAL; 898 + } 896 899 } 897 900 898 - static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 901 + static int mt9t112_set_selection(struct v4l2_subdev *sd, 902 + struct v4l2_subdev_pad_config *cfg, 903 + struct v4l2_subdev_selection *sel) 899 904 { 900 905 struct i2c_client *client = v4l2_get_subdevdata(sd); 901 906 struct mt9t112_priv *priv = to_mt9t112(client); 902 - const struct v4l2_rect *rect = &a->c; 907 + const struct v4l2_rect *rect = &sel->r; 908 + 909 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 910 + sel->target != V4L2_SEL_TGT_CROP) 911 + return -EINVAL; 903 912 904 913 return mt9t112_set_params(priv, rect, priv->format->code); 905 914 } ··· 1033 1024 1034 1025 static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { 1035 1026 .s_stream = mt9t112_s_stream, 1036 - .cropcap = mt9t112_cropcap, 1037 - .g_crop = mt9t112_g_crop, 1038 - .s_crop = mt9t112_s_crop, 1039 1027 .g_mbus_config = mt9t112_g_mbus_config, 1040 1028 .s_mbus_config = mt9t112_s_mbus_config, 1041 1029 }; 1042 1030 1043 1031 static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { 1044 1032 .enum_mbus_code = mt9t112_enum_mbus_code, 1033 + .get_selection = mt9t112_get_selection, 1034 + .set_selection = mt9t112_set_selection, 1045 1035 .get_fmt = mt9t112_get_fmt, 1046 1036 .set_fmt = mt9t112_set_fmt, 1047 1037 };
+37 -31
drivers/media/i2c/soc_camera/mt9v022.c
··· 276 276 return 0; 277 277 } 278 278 279 - static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 279 + static int mt9v022_set_selection(struct v4l2_subdev *sd, 280 + struct v4l2_subdev_pad_config *cfg, 281 + struct v4l2_subdev_selection *sel) 280 282 { 281 283 struct i2c_client *client = v4l2_get_subdevdata(sd); 282 284 struct mt9v022 *mt9v022 = to_mt9v022(client); 283 - struct v4l2_rect rect = a->c; 285 + struct v4l2_rect rect = sel->r; 284 286 int min_row, min_blank; 285 287 int ret; 288 + 289 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 290 + sel->target != V4L2_SEL_TGT_CROP) 291 + return -EINVAL; 286 292 287 293 /* Bayer format - even size lengths */ 288 294 if (mt9v022->fmts == mt9v022_colour_fmts) { ··· 356 350 return 0; 357 351 } 358 352 359 - static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 353 + static int mt9v022_get_selection(struct v4l2_subdev *sd, 354 + struct v4l2_subdev_pad_config *cfg, 355 + struct v4l2_subdev_selection *sel) 360 356 { 361 357 struct i2c_client *client = v4l2_get_subdevdata(sd); 362 358 struct mt9v022 *mt9v022 = to_mt9v022(client); 363 359 364 - a->c = mt9v022->rect; 365 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 360 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 361 + return -EINVAL; 366 362 367 - return 0; 368 - } 369 - 370 - static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 371 - { 372 - a->bounds.left = MT9V022_COLUMN_SKIP; 373 - a->bounds.top = MT9V022_ROW_SKIP; 374 - a->bounds.width = MT9V022_MAX_WIDTH; 375 - a->bounds.height = MT9V022_MAX_HEIGHT; 376 - a->defrect = a->bounds; 377 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 378 - a->pixelaspect.numerator = 1; 379 - a->pixelaspect.denominator = 1; 380 - 381 - return 0; 363 + switch (sel->target) { 364 + case V4L2_SEL_TGT_CROP_BOUNDS: 365 + case V4L2_SEL_TGT_CROP_DEFAULT: 366 + sel->r.left = MT9V022_COLUMN_SKIP; 367 + sel->r.top = MT9V022_ROW_SKIP; 368 + sel->r.width = MT9V022_MAX_WIDTH; 369 + sel->r.height = MT9V022_MAX_HEIGHT; 370 + return 0; 371 + case V4L2_SEL_TGT_CROP: 372 + sel->r = mt9v022->rect; 373 + return 0; 374 + default: 375 + return -EINVAL; 376 + } 382 377 } 383 378 384 379 static int mt9v022_get_fmt(struct v4l2_subdev *sd, ··· 407 400 { 408 401 struct i2c_client *client = v4l2_get_subdevdata(sd); 409 402 struct mt9v022 *mt9v022 = to_mt9v022(client); 410 - struct v4l2_crop a = { 411 - .c = { 412 - .left = mt9v022->rect.left, 413 - .top = mt9v022->rect.top, 414 - .width = mf->width, 415 - .height = mf->height, 416 - }, 403 + struct v4l2_subdev_selection sel = { 404 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 405 + .target = V4L2_SEL_TGT_CROP, 406 + .r.left = mt9v022->rect.left, 407 + .r.top = mt9v022->rect.top, 408 + .r.width = mf->width, 409 + .r.height = mf->height, 417 410 }; 418 411 int ret; 419 412 ··· 437 430 } 438 431 439 432 /* No support for scaling on this camera, just crop. */ 440 - ret = mt9v022_s_crop(sd, &a); 433 + ret = mt9v022_set_selection(sd, NULL, &sel); 441 434 if (!ret) { 442 435 mf->width = mt9v022->rect.width; 443 436 mf->height = mt9v022->rect.height; ··· 860 853 861 854 static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 862 855 .s_stream = mt9v022_s_stream, 863 - .s_crop = mt9v022_s_crop, 864 - .g_crop = mt9v022_g_crop, 865 - .cropcap = mt9v022_cropcap, 866 856 .g_mbus_config = mt9v022_g_mbus_config, 867 857 .s_mbus_config = mt9v022_s_mbus_config, 868 858 }; ··· 870 866 871 867 static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { 872 868 .enum_mbus_code = mt9v022_enum_mbus_code, 869 + .get_selection = mt9v022_get_selection, 870 + .set_selection = mt9v022_set_selection, 873 871 .get_fmt = mt9v022_get_fmt, 874 872 .set_fmt = mt9v022_set_fmt, 875 873 };
+18 -23
drivers/media/i2c/soc_camera/ov2640.c
··· 928 928 return 0; 929 929 } 930 930 931 - static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 931 + static int ov2640_get_selection(struct v4l2_subdev *sd, 932 + struct v4l2_subdev_pad_config *cfg, 933 + struct v4l2_subdev_selection *sel) 932 934 { 933 - a->c.left = 0; 934 - a->c.top = 0; 935 - a->c.width = UXGA_WIDTH; 936 - a->c.height = UXGA_HEIGHT; 937 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 935 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 936 + return -EINVAL; 938 937 939 - return 0; 940 - } 941 - 942 - static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 943 - { 944 - a->bounds.left = 0; 945 - a->bounds.top = 0; 946 - a->bounds.width = UXGA_WIDTH; 947 - a->bounds.height = UXGA_HEIGHT; 948 - a->defrect = a->bounds; 949 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 950 - a->pixelaspect.numerator = 1; 951 - a->pixelaspect.denominator = 1; 952 - 953 - return 0; 938 + switch (sel->target) { 939 + case V4L2_SEL_TGT_CROP_BOUNDS: 940 + case V4L2_SEL_TGT_CROP_DEFAULT: 941 + case V4L2_SEL_TGT_CROP: 942 + sel->r.left = 0; 943 + sel->r.top = 0; 944 + sel->r.width = UXGA_WIDTH; 945 + sel->r.height = UXGA_HEIGHT; 946 + return 0; 947 + default: 948 + return -EINVAL; 949 + } 954 950 } 955 951 956 952 static int ov2640_video_probe(struct i2c_client *client) ··· 1020 1024 1021 1025 static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { 1022 1026 .s_stream = ov2640_s_stream, 1023 - .cropcap = ov2640_cropcap, 1024 - .g_crop = ov2640_g_crop, 1025 1027 .g_mbus_config = ov2640_g_mbus_config, 1026 1028 }; 1027 1029 1028 1030 static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { 1029 1031 .enum_mbus_code = ov2640_enum_mbus_code, 1032 + .get_selection = ov2640_get_selection, 1030 1033 .get_fmt = ov2640_get_fmt, 1031 1034 .set_fmt = ov2640_set_fmt, 1032 1035 };
+28 -25
drivers/media/i2c/soc_camera/ov5642.c
··· 850 850 return 0; 851 851 } 852 852 853 - static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 853 + static int ov5642_set_selection(struct v4l2_subdev *sd, 854 + struct v4l2_subdev_pad_config *cfg, 855 + struct v4l2_subdev_selection *sel) 854 856 { 855 857 struct i2c_client *client = v4l2_get_subdevdata(sd); 856 858 struct ov5642 *priv = to_ov5642(client); 857 - struct v4l2_rect rect = a->c; 859 + struct v4l2_rect rect = sel->r; 858 860 int ret; 861 + 862 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 863 + sel->target != V4L2_SEL_TGT_CROP) 864 + return -EINVAL; 859 865 860 866 v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1, 861 867 &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0); ··· 884 878 return ret; 885 879 } 886 880 887 - static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 881 + static int ov5642_get_selection(struct v4l2_subdev *sd, 882 + struct v4l2_subdev_pad_config *cfg, 883 + struct v4l2_subdev_selection *sel) 888 884 { 889 885 struct i2c_client *client = v4l2_get_subdevdata(sd); 890 886 struct ov5642 *priv = to_ov5642(client); 891 - struct v4l2_rect *rect = &a->c; 892 887 893 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 888 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 894 889 return -EINVAL; 895 890 896 - *rect = priv->crop_rect; 897 - 898 - return 0; 899 - } 900 - 901 - static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 902 - { 903 - a->bounds.left = 0; 904 - a->bounds.top = 0; 905 - a->bounds.width = OV5642_MAX_WIDTH; 906 - a->bounds.height = OV5642_MAX_HEIGHT; 907 - a->defrect = a->bounds; 908 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 909 - a->pixelaspect.numerator = 1; 910 - a->pixelaspect.denominator = 1; 911 - 912 - return 0; 891 + switch (sel->target) { 892 + case V4L2_SEL_TGT_CROP_BOUNDS: 893 + case V4L2_SEL_TGT_CROP_DEFAULT: 894 + sel->r.left = 0; 895 + sel->r.top = 0; 896 + sel->r.width = OV5642_MAX_WIDTH; 897 + sel->r.height = OV5642_MAX_HEIGHT; 898 + return 0; 899 + case V4L2_SEL_TGT_CROP: 900 + sel->r = priv->crop_rect; 901 + return 0; 902 + default: 903 + return -EINVAL; 904 + } 913 905 } 914 906 915 907 static int ov5642_g_mbus_config(struct v4l2_subdev *sd, ··· 944 940 } 945 941 946 942 static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { 947 - .s_crop = ov5642_s_crop, 948 - .g_crop = ov5642_g_crop, 949 - .cropcap = ov5642_cropcap, 950 943 .g_mbus_config = ov5642_g_mbus_config, 951 944 }; 952 945 953 946 static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { 954 947 .enum_mbus_code = ov5642_enum_mbus_code, 948 + .get_selection = ov5642_get_selection, 949 + .set_selection = ov5642_set_selection, 955 950 .get_fmt = ov5642_get_fmt, 956 951 .set_fmt = ov5642_set_fmt, 957 952 };
+37 -37
drivers/media/i2c/soc_camera/ov6650.c
··· 432 432 return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); 433 433 } 434 434 435 - static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 435 + static int ov6650_get_selection(struct v4l2_subdev *sd, 436 + struct v4l2_subdev_pad_config *cfg, 437 + struct v4l2_subdev_selection *sel) 436 438 { 437 439 struct i2c_client *client = v4l2_get_subdevdata(sd); 438 440 struct ov6650 *priv = to_ov6650(client); 439 441 440 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 441 - a->c = priv->rect; 442 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 443 + return -EINVAL; 442 444 443 - return 0; 445 + switch (sel->target) { 446 + case V4L2_SEL_TGT_CROP_BOUNDS: 447 + case V4L2_SEL_TGT_CROP_DEFAULT: 448 + sel->r.left = DEF_HSTRT << 1; 449 + sel->r.top = DEF_VSTRT << 1; 450 + sel->r.width = W_CIF; 451 + sel->r.height = H_CIF; 452 + return 0; 453 + case V4L2_SEL_TGT_CROP: 454 + sel->r = priv->rect; 455 + return 0; 456 + default: 457 + return -EINVAL; 458 + } 444 459 } 445 460 446 - static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 461 + static int ov6650_set_selection(struct v4l2_subdev *sd, 462 + struct v4l2_subdev_pad_config *cfg, 463 + struct v4l2_subdev_selection *sel) 447 464 { 448 465 struct i2c_client *client = v4l2_get_subdevdata(sd); 449 466 struct ov6650 *priv = to_ov6650(client); 450 - struct v4l2_rect rect = a->c; 467 + struct v4l2_rect rect = sel->r; 451 468 int ret; 452 469 453 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 470 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 471 + sel->target != V4L2_SEL_TGT_CROP) 454 472 return -EINVAL; 455 473 456 474 rect.left = ALIGN(rect.left, 2); ··· 499 481 priv->rect.height = rect.height; 500 482 501 483 return ret; 502 - } 503 - 504 - static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 505 - { 506 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 507 - return -EINVAL; 508 - 509 - a->bounds.left = DEF_HSTRT << 1; 510 - a->bounds.top = DEF_VSTRT << 1; 511 - a->bounds.width = W_CIF; 512 - a->bounds.height = H_CIF; 513 - a->defrect = a->bounds; 514 - a->pixelaspect.numerator = 1; 515 - a->pixelaspect.denominator = 1; 516 - 517 - return 0; 518 484 } 519 485 520 486 static int ov6650_get_fmt(struct v4l2_subdev *sd, ··· 551 549 struct soc_camera_sense *sense = icd->sense; 552 550 struct ov6650 *priv = to_ov6650(client); 553 551 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); 554 - struct v4l2_crop a = { 555 - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 556 - .c = { 557 - .left = priv->rect.left + (priv->rect.width >> 1) - 558 - (mf->width >> (1 - half_scale)), 559 - .top = priv->rect.top + (priv->rect.height >> 1) - 560 - (mf->height >> (1 - half_scale)), 561 - .width = mf->width << half_scale, 562 - .height = mf->height << half_scale, 563 - }, 552 + struct v4l2_subdev_selection sel = { 553 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 554 + .target = V4L2_SEL_TGT_CROP, 555 + .r.left = priv->rect.left + (priv->rect.width >> 1) - 556 + (mf->width >> (1 - half_scale)), 557 + .r.top = priv->rect.top + (priv->rect.height >> 1) - 558 + (mf->height >> (1 - half_scale)), 559 + .r.width = mf->width << half_scale, 560 + .r.height = mf->height << half_scale, 564 561 }; 565 562 u32 code = mf->code; 566 563 unsigned long mclk, pclk; ··· 673 672 dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", 674 673 mclk / pclk, 10 * mclk % pclk / pclk); 675 674 676 - ret = ov6650_s_crop(sd, &a); 675 + ret = ov6650_set_selection(sd, NULL, &sel); 677 676 if (!ret) 678 677 ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); 679 678 if (!ret) ··· 944 943 945 944 static struct v4l2_subdev_video_ops ov6650_video_ops = { 946 945 .s_stream = ov6650_s_stream, 947 - .cropcap = ov6650_cropcap, 948 - .g_crop = ov6650_g_crop, 949 - .s_crop = ov6650_s_crop, 950 946 .g_parm = ov6650_g_parm, 951 947 .s_parm = ov6650_s_parm, 952 948 .g_mbus_config = ov6650_g_mbus_config, ··· 952 954 953 955 static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { 954 956 .enum_mbus_code = ov6650_enum_mbus_code, 957 + .get_selection = ov6650_get_selection, 958 + .set_selection = ov6650_set_selection, 955 959 .get_fmt = ov6650_get_fmt, 956 960 .set_fmt = ov6650_set_fmt, 957 961 };
+21 -23
drivers/media/i2c/soc_camera/ov772x.c
··· 851 851 return ret; 852 852 } 853 853 854 - static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 854 + static int ov772x_get_selection(struct v4l2_subdev *sd, 855 + struct v4l2_subdev_pad_config *cfg, 856 + struct v4l2_subdev_selection *sel) 855 857 { 856 - a->c.left = 0; 857 - a->c.top = 0; 858 - a->c.width = VGA_WIDTH; 859 - a->c.height = VGA_HEIGHT; 860 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 858 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 859 + return -EINVAL; 861 860 862 - return 0; 863 - } 864 - 865 - static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 866 - { 867 - a->bounds.left = 0; 868 - a->bounds.top = 0; 869 - a->bounds.width = OV772X_MAX_WIDTH; 870 - a->bounds.height = OV772X_MAX_HEIGHT; 871 - a->defrect = a->bounds; 872 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 873 - a->pixelaspect.numerator = 1; 874 - a->pixelaspect.denominator = 1; 875 - 876 - return 0; 861 + sel->r.left = 0; 862 + sel->r.top = 0; 863 + switch (sel->target) { 864 + case V4L2_SEL_TGT_CROP_BOUNDS: 865 + case V4L2_SEL_TGT_CROP_DEFAULT: 866 + sel->r.width = OV772X_MAX_WIDTH; 867 + sel->r.height = OV772X_MAX_HEIGHT; 868 + return 0; 869 + case V4L2_SEL_TGT_CROP: 870 + sel->r.width = VGA_WIDTH; 871 + sel->r.height = VGA_HEIGHT; 872 + return 0; 873 + default: 874 + return -EINVAL; 875 + } 877 876 } 878 877 879 878 static int ov772x_get_fmt(struct v4l2_subdev *sd, ··· 1029 1030 1030 1031 static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1031 1032 .s_stream = ov772x_s_stream, 1032 - .cropcap = ov772x_cropcap, 1033 - .g_crop = ov772x_g_crop, 1034 1033 .g_mbus_config = ov772x_g_mbus_config, 1035 1034 }; 1036 1035 1037 1036 static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { 1038 1037 .enum_mbus_code = ov772x_enum_mbus_code, 1038 + .get_selection = ov772x_get_selection, 1039 1039 .get_fmt = ov772x_get_fmt, 1040 1040 .set_fmt = ov772x_set_fmt, 1041 1041 };
+18 -23
drivers/media/i2c/soc_camera/ov9640.c
··· 561 561 return 0; 562 562 } 563 563 564 - static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 564 + static int ov9640_get_selection(struct v4l2_subdev *sd, 565 + struct v4l2_subdev_pad_config *cfg, 566 + struct v4l2_subdev_selection *sel) 565 567 { 566 - a->c.left = 0; 567 - a->c.top = 0; 568 - a->c.width = W_SXGA; 569 - a->c.height = H_SXGA; 570 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 568 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 569 + return -EINVAL; 571 570 572 - return 0; 573 - } 574 - 575 - static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 576 - { 577 - a->bounds.left = 0; 578 - a->bounds.top = 0; 579 - a->bounds.width = W_SXGA; 580 - a->bounds.height = H_SXGA; 581 - a->defrect = a->bounds; 582 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 583 - a->pixelaspect.numerator = 1; 584 - a->pixelaspect.denominator = 1; 585 - 586 - return 0; 571 + sel->r.left = 0; 572 + sel->r.top = 0; 573 + switch (sel->target) { 574 + case V4L2_SEL_TGT_CROP_BOUNDS: 575 + case V4L2_SEL_TGT_CROP_DEFAULT: 576 + case V4L2_SEL_TGT_CROP: 577 + sel->r.width = W_SXGA; 578 + sel->r.height = H_SXGA; 579 + return 0; 580 + default: 581 + return -EINVAL; 582 + } 587 583 } 588 584 589 585 static int ov9640_video_probe(struct i2c_client *client) ··· 663 667 664 668 static struct v4l2_subdev_video_ops ov9640_video_ops = { 665 669 .s_stream = ov9640_s_stream, 666 - .cropcap = ov9640_cropcap, 667 - .g_crop = ov9640_g_crop, 668 670 .g_mbus_config = ov9640_g_mbus_config, 669 671 }; 670 672 671 673 static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { 672 674 .enum_mbus_code = ov9640_enum_mbus_code, 675 + .get_selection = ov9640_get_selection, 673 676 .set_fmt = ov9640_set_fmt, 674 677 }; 675 678
+18 -23
drivers/media/i2c/soc_camera/ov9740.c
··· 737 737 return 0; 738 738 } 739 739 740 - static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 740 + static int ov9740_get_selection(struct v4l2_subdev *sd, 741 + struct v4l2_subdev_pad_config *cfg, 742 + struct v4l2_subdev_selection *sel) 741 743 { 742 - a->bounds.left = 0; 743 - a->bounds.top = 0; 744 - a->bounds.width = OV9740_MAX_WIDTH; 745 - a->bounds.height = OV9740_MAX_HEIGHT; 746 - a->defrect = a->bounds; 747 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 748 - a->pixelaspect.numerator = 1; 749 - a->pixelaspect.denominator = 1; 744 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 745 + return -EINVAL; 750 746 751 - return 0; 752 - } 753 - 754 - static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 755 - { 756 - a->c.left = 0; 757 - a->c.top = 0; 758 - a->c.width = OV9740_MAX_WIDTH; 759 - a->c.height = OV9740_MAX_HEIGHT; 760 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 761 - 762 - return 0; 747 + switch (sel->target) { 748 + case V4L2_SEL_TGT_CROP_BOUNDS: 749 + case V4L2_SEL_TGT_CROP_DEFAULT: 750 + case V4L2_SEL_TGT_CROP: 751 + sel->r.left = 0; 752 + sel->r.top = 0; 753 + sel->r.width = OV9740_MAX_WIDTH; 754 + sel->r.height = OV9740_MAX_HEIGHT; 755 + return 0; 756 + default: 757 + return -EINVAL; 758 + } 763 759 } 764 760 765 761 /* Set status of additional camera capabilities */ ··· 910 914 911 915 static struct v4l2_subdev_video_ops ov9740_video_ops = { 912 916 .s_stream = ov9740_s_stream, 913 - .cropcap = ov9740_cropcap, 914 - .g_crop = ov9740_g_crop, 915 917 .g_mbus_config = ov9740_g_mbus_config, 916 918 }; 917 919 ··· 923 929 924 930 static const struct v4l2_subdev_pad_ops ov9740_pad_ops = { 925 931 .enum_mbus_code = ov9740_enum_mbus_code, 932 + .get_selection = ov9740_get_selection, 926 933 .set_fmt = ov9740_set_fmt, 927 934 }; 928 935
+29 -23
drivers/media/i2c/soc_camera/rj54n1cb0c.c
··· 538 538 static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, 539 539 s32 *out_w, s32 *out_h); 540 540 541 - static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 541 + static int rj54n1_set_selection(struct v4l2_subdev *sd, 542 + struct v4l2_subdev_pad_config *cfg, 543 + struct v4l2_subdev_selection *sel) 542 544 { 543 545 struct i2c_client *client = v4l2_get_subdevdata(sd); 544 546 struct rj54n1 *rj54n1 = to_rj54n1(client); 545 - const struct v4l2_rect *rect = &a->c; 547 + const struct v4l2_rect *rect = &sel->r; 546 548 int dummy = 0, output_w, output_h, 547 549 input_w = rect->width, input_h = rect->height; 548 550 int ret; 551 + 552 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 553 + sel->target != V4L2_SEL_TGT_CROP) 554 + return -EINVAL; 549 555 550 556 /* arbitrary minimum width and height, edges unimportant */ 551 557 soc_camera_limit_side(&dummy, &input_w, ··· 579 573 return 0; 580 574 } 581 575 582 - static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 576 + static int rj54n1_get_selection(struct v4l2_subdev *sd, 577 + struct v4l2_subdev_pad_config *cfg, 578 + struct v4l2_subdev_selection *sel) 583 579 { 584 580 struct i2c_client *client = v4l2_get_subdevdata(sd); 585 581 struct rj54n1 *rj54n1 = to_rj54n1(client); 586 582 587 - a->c = rj54n1->rect; 588 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 583 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 584 + return -EINVAL; 589 585 590 - return 0; 591 - } 592 - 593 - static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 594 - { 595 - a->bounds.left = RJ54N1_COLUMN_SKIP; 596 - a->bounds.top = RJ54N1_ROW_SKIP; 597 - a->bounds.width = RJ54N1_MAX_WIDTH; 598 - a->bounds.height = RJ54N1_MAX_HEIGHT; 599 - a->defrect = a->bounds; 600 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 601 - a->pixelaspect.numerator = 1; 602 - a->pixelaspect.denominator = 1; 603 - 604 - return 0; 586 + switch (sel->target) { 587 + case V4L2_SEL_TGT_CROP_BOUNDS: 588 + case V4L2_SEL_TGT_CROP_DEFAULT: 589 + sel->r.left = RJ54N1_COLUMN_SKIP; 590 + sel->r.top = RJ54N1_ROW_SKIP; 591 + sel->r.width = RJ54N1_MAX_WIDTH; 592 + sel->r.height = RJ54N1_MAX_HEIGHT; 593 + return 0; 594 + case V4L2_SEL_TGT_CROP: 595 + sel->r = rj54n1->rect; 596 + return 0; 597 + default: 598 + return -EINVAL; 599 + } 605 600 } 606 601 607 602 static int rj54n1_get_fmt(struct v4l2_subdev *sd, ··· 1253 1246 1254 1247 static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { 1255 1248 .s_stream = rj54n1_s_stream, 1256 - .g_crop = rj54n1_g_crop, 1257 - .s_crop = rj54n1_s_crop, 1258 - .cropcap = rj54n1_cropcap, 1259 1249 .g_mbus_config = rj54n1_g_mbus_config, 1260 1250 .s_mbus_config = rj54n1_s_mbus_config, 1261 1251 }; 1262 1252 1263 1253 static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = { 1264 1254 .enum_mbus_code = rj54n1_enum_mbus_code, 1255 + .get_selection = rj54n1_get_selection, 1256 + .set_selection = rj54n1_set_selection, 1265 1257 .get_fmt = rj54n1_get_fmt, 1266 1258 .set_fmt = rj54n1_set_fmt, 1267 1259 };
+16 -33
drivers/media/i2c/soc_camera/tw9910.c
··· 676 676 return ret; 677 677 } 678 678 679 - static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 679 + static int tw9910_get_selection(struct v4l2_subdev *sd, 680 + struct v4l2_subdev_pad_config *cfg, 681 + struct v4l2_subdev_selection *sel) 680 682 { 681 683 struct i2c_client *client = v4l2_get_subdevdata(sd); 682 684 struct tw9910_priv *priv = to_tw9910(client); 683 685 684 - a->c.left = 0; 685 - a->c.top = 0; 686 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 687 + return -EINVAL; 688 + /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */ 689 + if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS) 690 + return -EINVAL; 691 + 692 + sel->r.left = 0; 693 + sel->r.top = 0; 686 694 if (priv->norm & V4L2_STD_NTSC) { 687 - a->c.width = 640; 688 - a->c.height = 480; 695 + sel->r.width = 640; 696 + sel->r.height = 480; 689 697 } else { 690 - a->c.width = 768; 691 - a->c.height = 576; 698 + sel->r.width = 768; 699 + sel->r.height = 576; 692 700 } 693 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 694 - 695 - return 0; 696 - } 697 - 698 - static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 699 - { 700 - struct i2c_client *client = v4l2_get_subdevdata(sd); 701 - struct tw9910_priv *priv = to_tw9910(client); 702 - 703 - a->bounds.left = 0; 704 - a->bounds.top = 0; 705 - if (priv->norm & V4L2_STD_NTSC) { 706 - a->bounds.width = 640; 707 - a->bounds.height = 480; 708 - } else { 709 - a->bounds.width = 768; 710 - a->bounds.height = 576; 711 - } 712 - a->defrect = a->bounds; 713 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 714 - a->pixelaspect.numerator = 1; 715 - a->pixelaspect.denominator = 1; 716 - 717 701 return 0; 718 702 } 719 703 ··· 905 921 .s_std = tw9910_s_std, 906 922 .g_std = tw9910_g_std, 907 923 .s_stream = tw9910_s_stream, 908 - .cropcap = tw9910_cropcap, 909 - .g_crop = tw9910_g_crop, 910 924 .g_mbus_config = tw9910_g_mbus_config, 911 925 .s_mbus_config = tw9910_s_mbus_config, 912 926 .g_tvnorms = tw9910_g_tvnorms, ··· 912 930 913 931 static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { 914 932 .enum_mbus_code = tw9910_enum_mbus_code, 933 + .get_selection = tw9910_get_selection, 915 934 .get_fmt = tw9910_get_fmt, 916 935 .set_fmt = tw9910_set_fmt, 917 936 };
+38 -41
drivers/media/i2c/tvp5150.c
··· 871 871 return 0; 872 872 } 873 873 874 - static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) 874 + static int tvp5150_set_selection(struct v4l2_subdev *sd, 875 + struct v4l2_subdev_pad_config *cfg, 876 + struct v4l2_subdev_selection *sel) 875 877 { 876 - struct v4l2_rect rect = a->c; 877 878 struct tvp5150 *decoder = to_tvp5150(sd); 879 + struct v4l2_rect rect = sel->r; 878 880 v4l2_std_id std; 879 - unsigned int hmax; 881 + int hmax; 882 + 883 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || 884 + sel->target != V4L2_SEL_TGT_CROP) 885 + return -EINVAL; 880 886 881 887 v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n", 882 888 __func__, rect.left, rect.top, rect.width, rect.height); 883 - 884 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 885 - return -EINVAL; 886 889 887 890 /* tvp5150 has some special limits */ 888 891 rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT); ··· 927 924 return 0; 928 925 } 929 926 930 - static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 927 + static int tvp5150_get_selection(struct v4l2_subdev *sd, 928 + struct v4l2_subdev_pad_config *cfg, 929 + struct v4l2_subdev_selection *sel) 931 930 { 932 - struct tvp5150 *decoder = to_tvp5150(sd); 933 - 934 - a->c = decoder->rect; 935 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 936 - 937 - return 0; 938 - } 939 - 940 - static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 941 - { 942 - struct tvp5150 *decoder = to_tvp5150(sd); 931 + struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); 943 932 v4l2_std_id std; 944 933 945 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 934 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 946 935 return -EINVAL; 947 936 948 - a->bounds.left = 0; 949 - a->bounds.top = 0; 950 - a->bounds.width = TVP5150_H_MAX; 937 + switch (sel->target) { 938 + case V4L2_SEL_TGT_CROP_BOUNDS: 939 + case V4L2_SEL_TGT_CROP_DEFAULT: 940 + sel->r.left = 0; 941 + sel->r.top = 0; 942 + sel->r.width = TVP5150_H_MAX; 951 943 952 - /* Calculate height based on current standard */ 953 - if (decoder->norm == V4L2_STD_ALL) 954 - std = tvp5150_read_std(sd); 955 - else 956 - std = decoder->norm; 957 - 958 - if (std & V4L2_STD_525_60) 959 - a->bounds.height = TVP5150_V_MAX_525_60; 960 - else 961 - a->bounds.height = TVP5150_V_MAX_OTHERS; 962 - 963 - a->defrect = a->bounds; 964 - a->pixelaspect.numerator = 1; 965 - a->pixelaspect.denominator = 1; 966 - 967 - return 0; 944 + /* Calculate height based on current standard */ 945 + if (decoder->norm == V4L2_STD_ALL) 946 + std = tvp5150_read_std(sd); 947 + else 948 + std = decoder->norm; 949 + if (std & V4L2_STD_525_60) 950 + sel->r.height = TVP5150_V_MAX_525_60; 951 + else 952 + sel->r.height = TVP5150_V_MAX_OTHERS; 953 + return 0; 954 + case V4L2_SEL_TGT_CROP: 955 + sel->r = decoder->rect; 956 + return 0; 957 + default: 958 + return -EINVAL; 959 + } 968 960 } 969 961 970 962 static int tvp5150_g_mbus_config(struct v4l2_subdev *sd, ··· 1231 1233 .s_std = tvp5150_s_std, 1232 1234 .s_stream = tvp5150_s_stream, 1233 1235 .s_routing = tvp5150_s_routing, 1234 - .s_crop = tvp5150_s_crop, 1235 - .g_crop = tvp5150_g_crop, 1236 - .cropcap = tvp5150_cropcap, 1237 1236 .g_mbus_config = tvp5150_g_mbus_config, 1238 1237 }; 1239 1238 ··· 1246 1251 .enum_frame_size = tvp5150_enum_frame_size, 1247 1252 .set_fmt = tvp5150_fill_fmt, 1248 1253 .get_fmt = tvp5150_fill_fmt, 1254 + .get_selection = tvp5150_get_selection, 1255 + .set_selection = tvp5150_set_selection, 1249 1256 }; 1250 1257 1251 1258 static const struct v4l2_subdev_ops tvp5150_ops = {
+57 -31
drivers/media/platform/omap3isp/ispvideo.c
··· 772 772 } 773 773 774 774 static int 775 - isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) 776 - { 777 - struct isp_video *video = video_drvdata(file); 778 - struct v4l2_subdev *subdev; 779 - int ret; 780 - 781 - subdev = isp_video_remote_subdev(video, NULL); 782 - if (subdev == NULL) 783 - return -EINVAL; 784 - 785 - mutex_lock(&video->mutex); 786 - ret = v4l2_subdev_call(subdev, video, cropcap, cropcap); 787 - mutex_unlock(&video->mutex); 788 - 789 - return ret == -ENOIOCTLCMD ? -ENOTTY : ret; 790 - } 791 - 792 - static int 793 - isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) 775 + isp_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) 794 776 { 795 777 struct isp_video *video = video_drvdata(file); 796 778 struct v4l2_subdev_format format; 797 779 struct v4l2_subdev *subdev; 780 + struct v4l2_subdev_selection sdsel = { 781 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 782 + .target = sel->target, 783 + }; 798 784 u32 pad; 799 785 int ret; 800 786 787 + switch (sel->target) { 788 + case V4L2_SEL_TGT_CROP: 789 + case V4L2_SEL_TGT_CROP_BOUNDS: 790 + case V4L2_SEL_TGT_CROP_DEFAULT: 791 + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 792 + return -EINVAL; 793 + break; 794 + case V4L2_SEL_TGT_COMPOSE: 795 + case V4L2_SEL_TGT_COMPOSE_BOUNDS: 796 + case V4L2_SEL_TGT_COMPOSE_DEFAULT: 797 + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 798 + return -EINVAL; 799 + break; 800 + default: 801 + return -EINVAL; 802 + } 801 803 subdev = isp_video_remote_subdev(video, &pad); 802 804 if (subdev == NULL) 803 805 return -EINVAL; 804 806 805 - /* Try the get crop operation first and fallback to get format if not 807 + /* Try the get selection operation first and fallback to get format if not 806 808 * implemented. 807 809 */ 808 - ret = v4l2_subdev_call(subdev, video, g_crop, crop); 810 + sdsel.pad = pad; 811 + ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); 812 + if (!ret) 813 + sel->r = sdsel.r; 809 814 if (ret != -ENOIOCTLCMD) 810 815 return ret; 811 816 ··· 820 815 if (ret < 0) 821 816 return ret == -ENOIOCTLCMD ? -ENOTTY : ret; 822 817 823 - crop->c.left = 0; 824 - crop->c.top = 0; 825 - crop->c.width = format.format.width; 826 - crop->c.height = format.format.height; 818 + sel->r.left = 0; 819 + sel->r.top = 0; 820 + sel->r.width = format.format.width; 821 + sel->r.height = format.format.height; 827 822 828 823 return 0; 829 824 } 830 825 831 826 static int 832 - isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) 827 + isp_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel) 833 828 { 834 829 struct isp_video *video = video_drvdata(file); 835 830 struct v4l2_subdev *subdev; 831 + struct v4l2_subdev_selection sdsel = { 832 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 833 + .target = sel->target, 834 + .flags = sel->flags, 835 + .r = sel->r, 836 + }; 837 + u32 pad; 836 838 int ret; 837 839 838 - subdev = isp_video_remote_subdev(video, NULL); 840 + switch (sel->target) { 841 + case V4L2_SEL_TGT_CROP: 842 + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 843 + return -EINVAL; 844 + break; 845 + case V4L2_SEL_TGT_COMPOSE: 846 + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 847 + return -EINVAL; 848 + break; 849 + default: 850 + return -EINVAL; 851 + } 852 + subdev = isp_video_remote_subdev(video, &pad); 839 853 if (subdev == NULL) 840 854 return -EINVAL; 841 855 856 + sdsel.pad = pad; 842 857 mutex_lock(&video->mutex); 843 - ret = v4l2_subdev_call(subdev, video, s_crop, crop); 858 + ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel); 844 859 mutex_unlock(&video->mutex); 860 + if (!ret) 861 + sel->r = sdsel.r; 845 862 846 863 return ret == -ENOIOCTLCMD ? -ENOTTY : ret; 847 864 } ··· 1279 1252 .vidioc_g_fmt_vid_out = isp_video_get_format, 1280 1253 .vidioc_s_fmt_vid_out = isp_video_set_format, 1281 1254 .vidioc_try_fmt_vid_out = isp_video_try_format, 1282 - .vidioc_cropcap = isp_video_cropcap, 1283 - .vidioc_g_crop = isp_video_get_crop, 1284 - .vidioc_s_crop = isp_video_set_crop, 1255 + .vidioc_g_selection = isp_video_get_selection, 1256 + .vidioc_s_selection = isp_video_set_selection, 1285 1257 .vidioc_g_parm = isp_video_get_param, 1286 1258 .vidioc_s_parm = isp_video_set_param, 1287 1259 .vidioc_reqbufs = isp_video_reqbufs,
+9 -6
drivers/media/platform/sh_vou.c
··· 937 937 { 938 938 struct v4l2_rect *rect = &sel->r; 939 939 struct sh_vou_device *vou_dev = video_drvdata(file); 940 - struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; 940 + struct v4l2_subdev_selection sd_sel = { 941 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 942 + .target = V4L2_SEL_TGT_COMPOSE, 943 + }; 941 944 struct v4l2_pix_format *pix = &vou_dev->pix; 942 945 struct sh_vou_geometry geo; 943 946 struct v4l2_subdev_format format = { ··· 981 978 geo.in_height = pix->height; 982 979 983 980 /* Configure the encoder one-to-one, position at 0, ignore errors */ 984 - sd_crop.c.width = geo.output.width; 985 - sd_crop.c.height = geo.output.height; 981 + sd_sel.r.width = geo.output.width; 982 + sd_sel.r.height = geo.output.height; 986 983 /* 987 - * We first issue a S_CROP, so that the subsequent S_FMT delivers the 984 + * We first issue a S_SELECTION, so that the subsequent S_FMT delivers the 988 985 * final encoder configuration. 989 986 */ 990 - v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, 991 - s_crop, &sd_crop); 987 + v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad, 988 + set_selection, NULL, &sd_sel); 992 989 format.format.width = geo.output.width; 993 990 format.format.height = geo.output.height; 994 991 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad,
+12 -5
drivers/media/platform/soc_camera/pxa_camera.c
··· 1280 1280 (width & 0x01); 1281 1281 } 1282 1282 1283 - static int pxa_camera_set_crop(struct soc_camera_device *icd, 1284 - const struct v4l2_crop *a) 1283 + static int pxa_camera_set_selection(struct soc_camera_device *icd, 1284 + struct v4l2_selection *sel) 1285 1285 { 1286 - const struct v4l2_rect *rect = &a->c; 1286 + const struct v4l2_rect *rect = &sel->r; 1287 1287 struct device *dev = icd->parent; 1288 1288 struct soc_camera_host *ici = to_soc_camera_host(dev); 1289 1289 struct pxa_camera_dev *pcdev = ici->priv; ··· 1298 1298 struct v4l2_mbus_framefmt *mf = &fmt.format; 1299 1299 struct pxa_cam *cam = icd->host_priv; 1300 1300 u32 fourcc = icd->current_fmt->host_fmt->fourcc; 1301 + struct v4l2_subdev_selection sdsel = { 1302 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1303 + .target = sel->target, 1304 + .flags = sel->flags, 1305 + .r = sel->r, 1306 + }; 1301 1307 int ret; 1302 1308 1303 1309 /* If PCLK is used to latch data from the sensor, check sense */ 1304 1310 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1305 1311 icd->sense = &sense; 1306 1312 1307 - ret = v4l2_subdev_call(sd, video, s_crop, a); 1313 + ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); 1308 1314 1309 1315 icd->sense = NULL; 1310 1316 ··· 1319 1313 rect->width, rect->height, rect->left, rect->top); 1320 1314 return ret; 1321 1315 } 1316 + sel->r = sdsel.r; 1322 1317 1323 1318 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); 1324 1319 if (ret < 0) ··· 1599 1592 .remove = pxa_camera_remove_device, 1600 1593 .clock_start = pxa_camera_clock_start, 1601 1594 .clock_stop = pxa_camera_clock_stop, 1602 - .set_crop = pxa_camera_set_crop, 1595 + .set_selection = pxa_camera_set_selection, 1603 1596 .get_formats = pxa_camera_get_formats, 1604 1597 .put_formats = pxa_camera_put_formats, 1605 1598 .set_fmt = pxa_camera_set_fmt,
+14 -16
drivers/media/platform/soc_camera/rcar_vin.c
··· 515 515 unsigned int out_width; 516 516 unsigned int out_height; 517 517 /* 518 - * User window from S_CROP / G_CROP, produced by client cropping and 518 + * User window from S_SELECTION / G_SELECTION, produced by client cropping and 519 519 * scaling, VIN scaling and VIN cropping, mapped back onto the client 520 520 * input window 521 521 */ ··· 1471 1471 icd->host_priv = NULL; 1472 1472 } 1473 1473 1474 - static int rcar_vin_set_crop(struct soc_camera_device *icd, 1475 - const struct v4l2_crop *a) 1474 + static int rcar_vin_set_selection(struct soc_camera_device *icd, 1475 + struct v4l2_selection *sel) 1476 1476 { 1477 - struct v4l2_crop a_writable = *a; 1478 - const struct v4l2_rect *rect = &a_writable.c; 1477 + const struct v4l2_rect *rect = &sel->r; 1479 1478 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1480 1479 struct rcar_vin_priv *priv = ici->priv; 1481 - struct v4l2_crop cam_crop; 1480 + struct v4l2_selection cam_sel; 1482 1481 struct rcar_vin_cam *cam = icd->host_priv; 1483 - struct v4l2_rect *cam_rect = &cam_crop.c; 1482 + struct v4l2_rect *cam_rect = &cam_sel.r; 1484 1483 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1485 1484 struct device *dev = icd->parent; 1486 1485 struct v4l2_subdev_format fmt = { ··· 1489 1490 u32 vnmc; 1490 1491 int ret, i; 1491 1492 1492 - dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height, 1493 + dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height, 1493 1494 rect->left, rect->top); 1494 1495 1495 1496 /* During camera cropping its output window can change too, stop VIN */ 1496 1497 capture_stop_preserve(priv, &vnmc); 1497 1498 dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc); 1498 1499 1499 - /* Apply iterative camera S_CROP for new input window. */ 1500 - ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop, 1500 + /* Apply iterative camera S_SELECTION for new input window. */ 1501 + ret = soc_camera_client_s_selection(sd, sel, &cam_sel, 1501 1502 &cam->rect, &cam->subrect); 1502 1503 if (ret < 0) 1503 1504 return ret; ··· 1550 1551 return ret; 1551 1552 } 1552 1553 1553 - static int rcar_vin_get_crop(struct soc_camera_device *icd, 1554 - struct v4l2_crop *a) 1554 + static int rcar_vin_get_selection(struct soc_camera_device *icd, 1555 + struct v4l2_selection *sel) 1555 1556 { 1556 1557 struct rcar_vin_cam *cam = icd->host_priv; 1557 1558 1558 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1559 - a->c = cam->subrect; 1559 + sel->r = cam->subrect; 1560 1560 1561 1561 return 0; 1562 1562 } ··· 1822 1824 .remove = rcar_vin_remove_device, 1823 1825 .get_formats = rcar_vin_get_formats, 1824 1826 .put_formats = rcar_vin_put_formats, 1825 - .get_crop = rcar_vin_get_crop, 1826 - .set_crop = rcar_vin_set_crop, 1827 + .get_selection = rcar_vin_get_selection, 1828 + .set_selection = rcar_vin_set_selection, 1827 1829 .try_fmt = rcar_vin_try_fmt, 1828 1830 .set_fmt = rcar_vin_set_fmt, 1829 1831 .poll = rcar_vin_poll,
+18 -20
drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
··· 134 134 unsigned int width; 135 135 unsigned int height; 136 136 /* 137 - * User window from S_CROP / G_CROP, produced by client cropping and 137 + * User window from S_SELECTION / G_SELECTION, produced by client cropping and 138 138 * scaling, CEU scaling and CEU cropping, mapped back onto the client 139 139 * input window 140 140 */ ··· 1109 1109 * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of 1110 1110 * scaling and cropping algorithms and for the meaning of referenced here steps. 1111 1111 */ 1112 - static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 1113 - const struct v4l2_crop *a) 1112 + static int sh_mobile_ceu_set_selection(struct soc_camera_device *icd, 1113 + struct v4l2_selection *sel) 1114 1114 { 1115 - struct v4l2_crop a_writable = *a; 1116 - const struct v4l2_rect *rect = &a_writable.c; 1115 + struct v4l2_rect *rect = &sel->r; 1117 1116 struct device *dev = icd->parent; 1118 1117 struct soc_camera_host *ici = to_soc_camera_host(dev); 1119 1118 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1120 - struct v4l2_crop cam_crop; 1119 + struct v4l2_selection cam_sel; 1121 1120 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1122 - struct v4l2_rect *cam_rect = &cam_crop.c; 1121 + struct v4l2_rect *cam_rect = &cam_sel.r; 1123 1122 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1124 1123 struct v4l2_subdev_format fmt = { 1125 1124 .which = V4L2_SUBDEV_FORMAT_ACTIVE, ··· 1130 1131 u32 capsr, cflcr; 1131 1132 int ret; 1132 1133 1133 - dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height, 1134 + dev_geo(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height, 1134 1135 rect->left, rect->top); 1135 1136 1136 1137 /* During camera cropping its output window can change too, stop CEU */ ··· 1138 1139 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); 1139 1140 1140 1141 /* 1141 - * 1. - 2. Apply iterative camera S_CROP for new input window, read back 1142 + * 1. - 2. Apply iterative camera S_SELECTION for new input window, read back 1142 1143 * actual camera rectangle. 1143 1144 */ 1144 - ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop, 1145 + ret = soc_camera_client_s_selection(sd, sel, &cam_sel, 1145 1146 &cam->rect, &cam->subrect); 1146 1147 if (ret < 0) 1147 1148 return ret; ··· 1250 1251 return ret; 1251 1252 } 1252 1253 1253 - static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd, 1254 - struct v4l2_crop *a) 1254 + static int sh_mobile_ceu_get_selection(struct soc_camera_device *icd, 1255 + struct v4l2_selection *sel) 1255 1256 { 1256 1257 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1257 1258 1258 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1259 - a->c = cam->subrect; 1259 + sel->r = cam->subrect; 1260 1260 1261 1261 return 0; 1262 1262 } ··· 1497 1499 return ret; 1498 1500 } 1499 1501 1500 - static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, 1501 - const struct v4l2_crop *a) 1502 + static int sh_mobile_ceu_set_liveselection(struct soc_camera_device *icd, 1503 + struct v4l2_selection *sel) 1502 1504 { 1503 1505 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1504 1506 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); ··· 1517 1519 "Client failed to stop the stream: %d\n", ret); 1518 1520 else 1519 1521 /* Do the crop, if it fails, there's nothing more we can do */ 1520 - sh_mobile_ceu_set_crop(icd, a); 1522 + sh_mobile_ceu_set_selection(icd, sel); 1521 1523 1522 1524 dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height); 1523 1525 ··· 1598 1600 .clock_stop = sh_mobile_ceu_clock_stop, 1599 1601 .get_formats = sh_mobile_ceu_get_formats, 1600 1602 .put_formats = sh_mobile_ceu_put_formats, 1601 - .get_crop = sh_mobile_ceu_get_crop, 1602 - .set_crop = sh_mobile_ceu_set_crop, 1603 - .set_livecrop = sh_mobile_ceu_set_livecrop, 1603 + .get_selection = sh_mobile_ceu_get_selection, 1604 + .set_selection = sh_mobile_ceu_set_selection, 1605 + .set_liveselection = sh_mobile_ceu_set_liveselection, 1604 1606 .set_fmt = sh_mobile_ceu_set_fmt, 1605 1607 .try_fmt = sh_mobile_ceu_try_fmt, 1606 1608 .poll = sh_mobile_ceu_poll,
+37 -93
drivers/media/platform/soc_camera/soc_camera.c
··· 581 581 dev_dbg(icd->pdev, "S_FMT(%c%c%c%c, %ux%u)\n", 582 582 pixfmtstr(pix->pixelformat), pix->width, pix->height); 583 583 584 - /* We always call try_fmt() before set_fmt() or set_crop() */ 584 + /* We always call try_fmt() before set_fmt() or set_selection() */ 585 585 ret = soc_camera_try_fmt(icd, f); 586 586 if (ret < 0) 587 587 return ret; ··· 1025 1025 return ret; 1026 1026 } 1027 1027 1028 - static int soc_camera_cropcap(struct file *file, void *fh, 1029 - struct v4l2_cropcap *a) 1030 - { 1031 - struct soc_camera_device *icd = file->private_data; 1032 - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1033 - 1034 - return ici->ops->cropcap(icd, a); 1035 - } 1036 - 1037 - static int soc_camera_g_crop(struct file *file, void *fh, 1038 - struct v4l2_crop *a) 1039 - { 1040 - struct soc_camera_device *icd = file->private_data; 1041 - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1042 - int ret; 1043 - 1044 - ret = ici->ops->get_crop(icd, a); 1045 - 1046 - return ret; 1047 - } 1048 - 1049 - /* 1050 - * According to the V4L2 API, drivers shall not update the struct v4l2_crop 1051 - * argument with the actual geometry, instead, the user shall use G_CROP to 1052 - * retrieve it. 1053 - */ 1054 - static int soc_camera_s_crop(struct file *file, void *fh, 1055 - const struct v4l2_crop *a) 1056 - { 1057 - struct soc_camera_device *icd = file->private_data; 1058 - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1059 - const struct v4l2_rect *rect = &a->c; 1060 - struct v4l2_crop current_crop; 1061 - int ret; 1062 - 1063 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1064 - return -EINVAL; 1065 - 1066 - dev_dbg(icd->pdev, "S_CROP(%ux%u@%u:%u)\n", 1067 - rect->width, rect->height, rect->left, rect->top); 1068 - 1069 - current_crop.type = a->type; 1070 - 1071 - /* If get_crop fails, we'll let host and / or client drivers decide */ 1072 - ret = ici->ops->get_crop(icd, &current_crop); 1073 - 1074 - /* Prohibit window size change with initialised buffers */ 1075 - if (ret < 0) { 1076 - dev_err(icd->pdev, 1077 - "S_CROP denied: getting current crop failed\n"); 1078 - } else if ((a->c.width == current_crop.c.width && 1079 - a->c.height == current_crop.c.height) || 1080 - !is_streaming(ici, icd)) { 1081 - /* same size or not streaming - use .set_crop() */ 1082 - ret = ici->ops->set_crop(icd, a); 1083 - } else if (ici->ops->set_livecrop) { 1084 - ret = ici->ops->set_livecrop(icd, a); 1085 - } else { 1086 - dev_err(icd->pdev, 1087 - "S_CROP denied: queue initialised and sizes differ\n"); 1088 - ret = -EBUSY; 1089 - } 1090 - 1091 - return ret; 1092 - } 1093 - 1094 1028 static int soc_camera_g_selection(struct file *file, void *fh, 1095 1029 struct v4l2_selection *s) 1096 1030 { ··· 1034 1100 /* With a wrong type no need to try to fall back to cropping */ 1035 1101 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1036 1102 return -EINVAL; 1037 - 1038 - if (!ici->ops->get_selection) 1039 - return -ENOTTY; 1040 1103 1041 1104 return ici->ops->get_selection(icd, s); 1042 1105 } ··· 1066 1135 return -EBUSY; 1067 1136 } 1068 1137 1069 - if (!ici->ops->set_selection) 1070 - return -ENOTTY; 1071 - 1072 - ret = ici->ops->set_selection(icd, s); 1138 + if (s->target == V4L2_SEL_TGT_CROP && is_streaming(ici, icd) && 1139 + ici->ops->set_liveselection) 1140 + ret = ici->ops->set_liveselection(icd, s); 1141 + else 1142 + ret = ici->ops->set_selection(icd, s); 1073 1143 if (!ret && 1074 1144 s->target == V4L2_SEL_TGT_COMPOSE) { 1075 1145 icd->user_width = s->r.width; ··· 1813 1881 return 0; 1814 1882 } 1815 1883 1816 - static int default_cropcap(struct soc_camera_device *icd, 1817 - struct v4l2_cropcap *a) 1884 + static int default_g_selection(struct soc_camera_device *icd, 1885 + struct v4l2_selection *sel) 1818 1886 { 1819 1887 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1820 - return v4l2_subdev_call(sd, video, cropcap, a); 1888 + struct v4l2_subdev_selection sdsel = { 1889 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1890 + .target = sel->target, 1891 + }; 1892 + int ret; 1893 + 1894 + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); 1895 + if (ret) 1896 + return ret; 1897 + sel->r = sdsel.r; 1898 + return 0; 1821 1899 } 1822 1900 1823 - static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a) 1901 + static int default_s_selection(struct soc_camera_device *icd, 1902 + struct v4l2_selection *sel) 1824 1903 { 1825 1904 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1826 - return v4l2_subdev_call(sd, video, g_crop, a); 1827 - } 1905 + struct v4l2_subdev_selection sdsel = { 1906 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1907 + .target = sel->target, 1908 + .flags = sel->flags, 1909 + .r = sel->r, 1910 + }; 1911 + int ret; 1828 1912 1829 - static int default_s_crop(struct soc_camera_device *icd, const struct v4l2_crop *a) 1830 - { 1831 - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1832 - return v4l2_subdev_call(sd, video, s_crop, a); 1913 + ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); 1914 + if (ret) 1915 + return ret; 1916 + sel->r = sdsel.r; 1917 + return 0; 1833 1918 } 1834 1919 1835 1920 static int default_g_parm(struct soc_camera_device *icd, ··· 1917 1968 !ici->v4l2_dev.dev) 1918 1969 return -EINVAL; 1919 1970 1920 - if (!ici->ops->set_crop) 1921 - ici->ops->set_crop = default_s_crop; 1922 - if (!ici->ops->get_crop) 1923 - ici->ops->get_crop = default_g_crop; 1924 - if (!ici->ops->cropcap) 1925 - ici->ops->cropcap = default_cropcap; 1971 + if (!ici->ops->set_selection) 1972 + ici->ops->set_selection = default_s_selection; 1973 + if (!ici->ops->get_selection) 1974 + ici->ops->get_selection = default_g_selection; 1926 1975 if (!ici->ops->set_parm) 1927 1976 ici->ops->set_parm = default_s_parm; 1928 1977 if (!ici->ops->get_parm) ··· 2073 2126 .vidioc_expbuf = soc_camera_expbuf, 2074 2127 .vidioc_streamon = soc_camera_streamon, 2075 2128 .vidioc_streamoff = soc_camera_streamoff, 2076 - .vidioc_cropcap = soc_camera_cropcap, 2077 - .vidioc_g_crop = soc_camera_g_crop, 2078 - .vidioc_s_crop = soc_camera_s_crop, 2079 2129 .vidioc_g_selection = soc_camera_g_selection, 2080 2130 .vidioc_s_selection = soc_camera_s_selection, 2081 2131 .vidioc_g_parm = soc_camera_g_parm,
+18 -27
drivers/media/platform/soc_camera/soc_camera_platform.c
··· 76 76 return 0; 77 77 } 78 78 79 - static int soc_camera_platform_g_crop(struct v4l2_subdev *sd, 80 - struct v4l2_crop *a) 79 + static int soc_camera_platform_get_selection(struct v4l2_subdev *sd, 80 + struct v4l2_subdev_pad_config *cfg, 81 + struct v4l2_subdev_selection *sel) 81 82 { 82 83 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 83 84 84 - a->c.left = 0; 85 - a->c.top = 0; 86 - a->c.width = p->format.width; 87 - a->c.height = p->format.height; 88 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 85 + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 86 + return -EINVAL; 89 87 90 - return 0; 91 - } 92 - 93 - static int soc_camera_platform_cropcap(struct v4l2_subdev *sd, 94 - struct v4l2_cropcap *a) 95 - { 96 - struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 97 - 98 - a->bounds.left = 0; 99 - a->bounds.top = 0; 100 - a->bounds.width = p->format.width; 101 - a->bounds.height = p->format.height; 102 - a->defrect = a->bounds; 103 - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 104 - a->pixelaspect.numerator = 1; 105 - a->pixelaspect.denominator = 1; 106 - 107 - return 0; 88 + switch (sel->target) { 89 + case V4L2_SEL_TGT_CROP_BOUNDS: 90 + case V4L2_SEL_TGT_CROP_DEFAULT: 91 + case V4L2_SEL_TGT_CROP: 92 + sel->r.left = 0; 93 + sel->r.top = 0; 94 + sel->r.width = p->format.width; 95 + sel->r.height = p->format.height; 96 + return 0; 97 + default: 98 + return -EINVAL; 99 + } 108 100 } 109 101 110 102 static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd, ··· 112 120 113 121 static struct v4l2_subdev_video_ops platform_subdev_video_ops = { 114 122 .s_stream = soc_camera_platform_s_stream, 115 - .cropcap = soc_camera_platform_cropcap, 116 - .g_crop = soc_camera_platform_g_crop, 117 123 .g_mbus_config = soc_camera_platform_g_mbus_config, 118 124 }; 119 125 120 126 static const struct v4l2_subdev_pad_ops platform_subdev_pad_ops = { 121 127 .enum_mbus_code = soc_camera_platform_enum_mbus_code, 128 + .get_selection = soc_camera_platform_get_selection, 122 129 .get_fmt = soc_camera_platform_fill_fmt, 123 130 .set_fmt = soc_camera_platform_fill_fmt, 124 131 };
+55 -42
drivers/media/platform/soc_camera/soc_scale_crop.c
··· 40 40 /* Get and store current client crop */ 41 41 int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) 42 42 { 43 - struct v4l2_crop crop; 44 - struct v4l2_cropcap cap; 43 + struct v4l2_subdev_selection sdsel = { 44 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 45 + .target = V4L2_SEL_TGT_CROP, 46 + }; 45 47 int ret; 46 48 47 - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 48 - 49 - ret = v4l2_subdev_call(sd, video, g_crop, &crop); 49 + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); 50 50 if (!ret) { 51 - *rect = crop.c; 51 + *rect = sdsel.r; 52 52 return ret; 53 53 } 54 54 55 - /* Camera driver doesn't support .g_crop(), assume default rectangle */ 56 - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 57 - 58 - ret = v4l2_subdev_call(sd, video, cropcap, &cap); 55 + sdsel.target = V4L2_SEL_TGT_CROP_DEFAULT; 56 + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); 59 57 if (!ret) 60 - *rect = cap.defrect; 58 + *rect = sdsel.r; 61 59 62 60 return ret; 63 61 } ··· 91 93 * 2. if (1) failed, try to double the client image until we get one big enough 92 94 * 3. if (2) failed, try to request the maximum image 93 95 */ 94 - int soc_camera_client_s_crop(struct v4l2_subdev *sd, 95 - struct v4l2_crop *crop, struct v4l2_crop *cam_crop, 96 + int soc_camera_client_s_selection(struct v4l2_subdev *sd, 97 + struct v4l2_selection *sel, struct v4l2_selection *cam_sel, 96 98 struct v4l2_rect *target_rect, struct v4l2_rect *subrect) 97 99 { 98 - struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; 100 + struct v4l2_subdev_selection sdsel = { 101 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 102 + .target = sel->target, 103 + .flags = sel->flags, 104 + .r = sel->r, 105 + }; 106 + struct v4l2_subdev_selection bounds = { 107 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 108 + .target = V4L2_SEL_TGT_CROP_BOUNDS, 109 + }; 110 + struct v4l2_rect *rect = &sel->r, *cam_rect = &cam_sel->r; 99 111 struct device *dev = sd->v4l2_dev->dev; 100 - struct v4l2_cropcap cap; 101 112 int ret; 102 113 unsigned int width, height; 103 114 104 - v4l2_subdev_call(sd, video, s_crop, crop); 115 + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); 116 + sel->r = sdsel.r; 105 117 ret = soc_camera_client_g_rect(sd, cam_rect); 106 118 if (ret < 0) 107 119 return ret; ··· 121 113 * be within camera cropcap bounds 122 114 */ 123 115 if (!memcmp(rect, cam_rect, sizeof(*rect))) { 124 - /* Even if camera S_CROP failed, but camera rectangle matches */ 125 - dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n", 116 + /* Even if camera S_SELECTION failed, but camera rectangle matches */ 117 + dev_dbg(dev, "Camera S_SELECTION successful for %dx%d@%d:%d\n", 126 118 rect->width, rect->height, rect->left, rect->top); 127 119 *target_rect = *cam_rect; 128 120 return 0; 129 121 } 130 122 131 123 /* Try to fix cropping, that camera hasn't managed to set */ 132 - dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n", 124 + dev_geo(dev, "Fix camera S_SELECTION for %dx%d@%d:%d to %dx%d@%d:%d\n", 133 125 cam_rect->width, cam_rect->height, 134 126 cam_rect->left, cam_rect->top, 135 127 rect->width, rect->height, rect->left, rect->top); 136 128 137 129 /* We need sensor maximum rectangle */ 138 - ret = v4l2_subdev_call(sd, video, cropcap, &cap); 130 + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &bounds); 139 131 if (ret < 0) 140 132 return ret; 141 133 142 134 /* Put user requested rectangle within sensor bounds */ 143 - soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2, 144 - cap.bounds.width); 145 - soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4, 146 - cap.bounds.height); 135 + soc_camera_limit_side(&rect->left, &rect->width, sdsel.r.left, 2, 136 + bounds.r.width); 137 + soc_camera_limit_side(&rect->top, &rect->height, sdsel.r.top, 4, 138 + bounds.r.height); 147 139 148 140 /* 149 141 * Popular special case - some cameras can only handle fixed sizes like ··· 158 150 */ 159 151 while (!ret && (is_smaller(cam_rect, rect) || 160 152 is_inside(cam_rect, rect)) && 161 - (cap.bounds.width > width || cap.bounds.height > height)) { 153 + (bounds.r.width > width || bounds.r.height > height)) { 162 154 163 155 width *= 2; 164 156 height *= 2; ··· 176 168 * Instead we just drop to the left and top bounds. 177 169 */ 178 170 if (cam_rect->left > rect->left) 179 - cam_rect->left = cap.bounds.left; 171 + cam_rect->left = bounds.r.left; 180 172 181 173 if (cam_rect->left + cam_rect->width < rect->left + rect->width) 182 174 cam_rect->width = rect->left + rect->width - 183 175 cam_rect->left; 184 176 185 177 if (cam_rect->top > rect->top) 186 - cam_rect->top = cap.bounds.top; 178 + cam_rect->top = bounds.r.top; 187 179 188 180 if (cam_rect->top + cam_rect->height < rect->top + rect->height) 189 181 cam_rect->height = rect->top + rect->height - 190 182 cam_rect->top; 191 183 192 - v4l2_subdev_call(sd, video, s_crop, cam_crop); 184 + sdsel.r = *cam_rect; 185 + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); 186 + *cam_rect = sdsel.r; 193 187 ret = soc_camera_client_g_rect(sd, cam_rect); 194 - dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret, 188 + dev_geo(dev, "Camera S_SELECTION %d for %dx%d@%d:%d\n", ret, 195 189 cam_rect->width, cam_rect->height, 196 190 cam_rect->left, cam_rect->top); 197 191 } 198 192 199 - /* S_CROP must not modify the rectangle */ 193 + /* S_SELECTION must not modify the rectangle */ 200 194 if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) { 201 195 /* 202 196 * The camera failed to configure a suitable cropping, 203 197 * we cannot use the current rectangle, set to max 204 198 */ 205 - *cam_rect = cap.bounds; 206 - v4l2_subdev_call(sd, video, s_crop, cam_crop); 199 + sdsel.r = bounds.r; 200 + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); 201 + *cam_rect = sdsel.r; 202 + 207 203 ret = soc_camera_client_g_rect(sd, cam_rect); 208 - dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret, 204 + dev_geo(dev, "Camera S_SELECTION %d for max %dx%d@%d:%d\n", ret, 209 205 cam_rect->width, cam_rect->height, 210 206 cam_rect->left, cam_rect->top); 211 207 } ··· 221 209 222 210 return ret; 223 211 } 224 - EXPORT_SYMBOL(soc_camera_client_s_crop); 212 + EXPORT_SYMBOL(soc_camera_client_s_selection); 225 213 226 214 /* Iterative set_fmt, also updates cached client crop on success */ 227 215 static int client_set_fmt(struct soc_camera_device *icd, ··· 233 221 struct device *dev = icd->parent; 234 222 struct v4l2_mbus_framefmt *mf = &format->format; 235 223 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 236 - struct v4l2_cropcap cap; 224 + struct v4l2_subdev_selection sdsel = { 225 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 226 + .target = V4L2_SEL_TGT_CROP_BOUNDS, 227 + }; 237 228 bool host_1to1; 238 229 int ret; 239 230 ··· 258 243 if (!host_can_scale) 259 244 goto update_cache; 260 245 261 - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 262 - 263 - ret = v4l2_subdev_call(sd, video, cropcap, &cap); 246 + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); 264 247 if (ret < 0) 265 248 return ret; 266 249 267 - if (max_width > cap.bounds.width) 268 - max_width = cap.bounds.width; 269 - if (max_height > cap.bounds.height) 270 - max_height = cap.bounds.height; 250 + if (max_width > sdsel.r.width) 251 + max_width = sdsel.r.width; 252 + if (max_height > sdsel.r.height) 253 + max_height = sdsel.r.height; 271 254 272 255 /* Camera set a format, but geometry is not precise, try to improve */ 273 256 tmp_w = mf->width;
+3 -3
drivers/media/platform/soc_camera/soc_scale_crop.h
··· 16 16 17 17 struct soc_camera_device; 18 18 19 - struct v4l2_crop; 19 + struct v4l2_selection; 20 20 struct v4l2_mbus_framefmt; 21 21 struct v4l2_pix_format; 22 22 struct v4l2_rect; ··· 31 31 #define soc_camera_calc_scale(in, shift, out) soc_camera_shift_scale(in, shift, out) 32 32 33 33 int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); 34 - int soc_camera_client_s_crop(struct v4l2_subdev *sd, 35 - struct v4l2_crop *crop, struct v4l2_crop *cam_crop, 34 + int soc_camera_client_s_selection(struct v4l2_subdev *sd, 35 + struct v4l2_selection *sel, struct v4l2_selection *cam_sel, 36 36 struct v4l2_rect *target_rect, struct v4l2_rect *subrect); 37 37 int soc_camera_client_scale(struct soc_camera_device *icd, 38 38 struct v4l2_rect *rect, struct v4l2_rect *subrect,
+99
drivers/staging/media/omap4iss/iss_video.c
··· 646 646 } 647 647 648 648 static int 649 + iss_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) 650 + { 651 + struct iss_video *video = video_drvdata(file); 652 + struct v4l2_subdev_format format; 653 + struct v4l2_subdev *subdev; 654 + struct v4l2_subdev_selection sdsel = { 655 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 656 + .target = sel->target, 657 + }; 658 + u32 pad; 659 + int ret; 660 + 661 + switch (sel->target) { 662 + case V4L2_SEL_TGT_CROP: 663 + case V4L2_SEL_TGT_CROP_BOUNDS: 664 + case V4L2_SEL_TGT_CROP_DEFAULT: 665 + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 666 + return -EINVAL; 667 + break; 668 + case V4L2_SEL_TGT_COMPOSE: 669 + case V4L2_SEL_TGT_COMPOSE_BOUNDS: 670 + case V4L2_SEL_TGT_COMPOSE_DEFAULT: 671 + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 672 + return -EINVAL; 673 + break; 674 + default: 675 + return -EINVAL; 676 + } 677 + subdev = iss_video_remote_subdev(video, &pad); 678 + if (subdev == NULL) 679 + return -EINVAL; 680 + 681 + /* Try the get selection operation first and fallback to get format if not 682 + * implemented. 683 + */ 684 + sdsel.pad = pad; 685 + ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); 686 + if (!ret) 687 + sel->r = sdsel.r; 688 + if (ret != -ENOIOCTLCMD) 689 + return ret; 690 + 691 + format.pad = pad; 692 + format.which = V4L2_SUBDEV_FORMAT_ACTIVE; 693 + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format); 694 + if (ret < 0) 695 + return ret == -ENOIOCTLCMD ? -ENOTTY : ret; 696 + 697 + sel->r.left = 0; 698 + sel->r.top = 0; 699 + sel->r.width = format.format.width; 700 + sel->r.height = format.format.height; 701 + 702 + return 0; 703 + } 704 + 705 + static int 706 + iss_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel) 707 + { 708 + struct iss_video *video = video_drvdata(file); 709 + struct v4l2_subdev *subdev; 710 + struct v4l2_subdev_selection sdsel = { 711 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 712 + .target = sel->target, 713 + .flags = sel->flags, 714 + .r = sel->r, 715 + }; 716 + u32 pad; 717 + int ret; 718 + 719 + switch (sel->target) { 720 + case V4L2_SEL_TGT_CROP: 721 + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 722 + return -EINVAL; 723 + break; 724 + case V4L2_SEL_TGT_COMPOSE: 725 + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 726 + return -EINVAL; 727 + break; 728 + default: 729 + return -EINVAL; 730 + } 731 + subdev = iss_video_remote_subdev(video, &pad); 732 + if (subdev == NULL) 733 + return -EINVAL; 734 + 735 + sdsel.pad = pad; 736 + mutex_lock(&video->mutex); 737 + ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel); 738 + mutex_unlock(&video->mutex); 739 + if (!ret) 740 + sel->r = sdsel.r; 741 + 742 + return ret == -ENOIOCTLCMD ? -ENOTTY : ret; 743 + } 744 + 745 + static int 649 746 iss_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a) 650 747 { 651 748 struct iss_video_fh *vfh = to_iss_video_fh(fh); ··· 1068 971 .vidioc_g_fmt_vid_out = iss_video_get_format, 1069 972 .vidioc_s_fmt_vid_out = iss_video_set_format, 1070 973 .vidioc_try_fmt_vid_out = iss_video_try_format, 974 + .vidioc_g_selection = iss_video_get_selection, 975 + .vidioc_s_selection = iss_video_set_selection, 1071 976 .vidioc_g_parm = iss_video_get_param, 1072 977 .vidioc_s_parm = iss_video_set_param, 1073 978 .vidioc_reqbufs = iss_video_reqbufs,
+2 -5
include/media/soc_camera.h
··· 105 105 int (*get_formats)(struct soc_camera_device *, unsigned int, 106 106 struct soc_camera_format_xlate *); 107 107 void (*put_formats)(struct soc_camera_device *); 108 - int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); 109 - int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *); 110 - int (*set_crop)(struct soc_camera_device *, const struct v4l2_crop *); 111 108 int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *); 112 109 int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *); 113 110 /* 114 - * The difference to .set_crop() is, that .set_livecrop is not allowed 111 + * The difference to .set_selection() is, that .set_liveselection is not allowed 115 112 * to change the output sizes 116 113 */ 117 - int (*set_livecrop)(struct soc_camera_device *, const struct v4l2_crop *); 114 + int (*set_liveselection)(struct soc_camera_device *, struct v4l2_selection *); 118 115 int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); 119 116 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 120 117 void (*init_videobuf)(struct videobuf_queue *,
-6
include/media/v4l2-subdev.h
··· 360 360 * 361 361 * @cropcap: callback for %VIDIOC_CROPCAP ioctl handler code. 362 362 * 363 - * @g_crop: callback for %VIDIOC_G_CROP ioctl handler code. 364 - * 365 - * @s_crop: callback for %VIDIOC_S_CROP ioctl handler code. 366 - * 367 363 * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code. 368 364 * 369 365 * @s_parm: callback for %VIDIOC_S_PARM ioctl handler code. ··· 399 403 int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); 400 404 int (*s_stream)(struct v4l2_subdev *sd, int enable); 401 405 int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); 402 - int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); 403 - int (*s_crop)(struct v4l2_subdev *sd, const struct v4l2_crop *crop); 404 406 int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 405 407 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 406 408 int (*g_frame_interval)(struct v4l2_subdev *sd,