aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-06-22 12:40:08 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-15 16:37:39 -0400
commit3bfb41001da5740b1c65ff537dfbff5904a4915d (patch)
tree96eccfdd9ea9718610d4e1f61ca16c02da9be25c /drivers/media/platform
parent1cb7cf28c0690852cfe5800e037fa0db9fba2432 (diff)
[media] V4L: soc-camera: add selection API host operations
Add .get_selection() and .set_selection() soc-camera host driver operations. Additionally check, that the user is not trying to change the output sizes during a running capture. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/soc_camera.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/media/platform/soc_camera.c b/drivers/media/platform/soc_camera.c
index f94055505d70..6da8e5db4d2b 100644
--- a/drivers/media/platform/soc_camera.c
+++ b/drivers/media/platform/soc_camera.c
@@ -924,6 +924,65 @@ static int soc_camera_s_crop(struct file *file, void *fh,
924 return ret; 924 return ret;
925} 925}
926 926
927static int soc_camera_g_selection(struct file *file, void *fh,
928 struct v4l2_selection *s)
929{
930 struct soc_camera_device *icd = file->private_data;
931 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
932
933 /* With a wrong type no need to try to fall back to cropping */
934 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
935 return -EINVAL;
936
937 if (!ici->ops->get_selection)
938 return -ENOTTY;
939
940 return ici->ops->get_selection(icd, s);
941}
942
943static int soc_camera_s_selection(struct file *file, void *fh,
944 struct v4l2_selection *s)
945{
946 struct soc_camera_device *icd = file->private_data;
947 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
948 int ret;
949
950 /* In all these cases cropping emulation will not help */
951 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
952 (s->target != V4L2_SEL_TGT_COMPOSE_ACTIVE &&
953 s->target != V4L2_SEL_TGT_CROP_ACTIVE))
954 return -EINVAL;
955
956 if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
957 /* No output size change during a running capture! */
958 if (is_streaming(ici, icd) &&
959 (icd->user_width != s->r.width ||
960 icd->user_height != s->r.height))
961 return -EBUSY;
962
963 /*
964 * Only one user is allowed to change the output format, touch
965 * buffers, start / stop streaming, poll for data
966 */
967 if (icd->streamer && icd->streamer != file)
968 return -EBUSY;
969 }
970
971 if (!ici->ops->set_selection)
972 return -ENOTTY;
973
974 ret = ici->ops->set_selection(icd, s);
975 if (!ret &&
976 s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
977 icd->user_width = s->r.width;
978 icd->user_height = s->r.height;
979 if (!icd->streamer)
980 icd->streamer = file;
981 }
982
983 return ret;
984}
985
927static int soc_camera_g_parm(struct file *file, void *fh, 986static int soc_camera_g_parm(struct file *file, void *fh,
928 struct v4l2_streamparm *a) 987 struct v4l2_streamparm *a)
929{ 988{
@@ -1407,6 +1466,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1407 .vidioc_cropcap = soc_camera_cropcap, 1466 .vidioc_cropcap = soc_camera_cropcap,
1408 .vidioc_g_crop = soc_camera_g_crop, 1467 .vidioc_g_crop = soc_camera_g_crop,
1409 .vidioc_s_crop = soc_camera_s_crop, 1468 .vidioc_s_crop = soc_camera_s_crop,
1469 .vidioc_g_selection = soc_camera_g_selection,
1470 .vidioc_s_selection = soc_camera_s_selection,
1410 .vidioc_g_parm = soc_camera_g_parm, 1471 .vidioc_g_parm = soc_camera_g_parm,
1411 .vidioc_s_parm = soc_camera_s_parm, 1472 .vidioc_s_parm = soc_camera_s_parm,
1412 .vidioc_g_chip_ident = soc_camera_g_chip_ident, 1473 .vidioc_g_chip_ident = soc_camera_g_chip_ident,