aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/v4l2-subdev.c42
-rw-r--r--include/linux/v4l2-subdev.h41
-rw-r--r--include/media/v4l2-subdev.h21
3 files changed, 90 insertions, 14 deletions
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 6fe88e965a8c..7d225389bfb1 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -35,14 +35,9 @@
35static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) 35static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
36{ 36{
37#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 37#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
38 /* Allocate try format and crop in the same memory block */ 38 fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
39 fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)) 39 if (fh->pad == NULL)
40 * sd->entity.num_pads, GFP_KERNEL);
41 if (fh->try_fmt == NULL)
42 return -ENOMEM; 40 return -ENOMEM;
43
44 fh->try_crop = (struct v4l2_rect *)
45 (fh->try_fmt + sd->entity.num_pads);
46#endif 41#endif
47 return 0; 42 return 0;
48} 43}
@@ -50,9 +45,8 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
50static void subdev_fh_free(struct v4l2_subdev_fh *fh) 45static void subdev_fh_free(struct v4l2_subdev_fh *fh)
51{ 46{
52#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 47#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
53 kfree(fh->try_fmt); 48 kfree(fh->pad);
54 fh->try_fmt = NULL; 49 fh->pad = NULL;
55 fh->try_crop = NULL;
56#endif 50#endif
57} 51}
58 52
@@ -293,6 +287,34 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
293 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh, 287 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
294 fie); 288 fie);
295 } 289 }
290
291 case VIDIOC_SUBDEV_G_SELECTION: {
292 struct v4l2_subdev_selection *sel = arg;
293
294 if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
295 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
296 return -EINVAL;
297
298 if (sel->pad >= sd->entity.num_pads)
299 return -EINVAL;
300
301 return v4l2_subdev_call(
302 sd, pad, get_selection, subdev_fh, sel);
303 }
304
305 case VIDIOC_SUBDEV_S_SELECTION: {
306 struct v4l2_subdev_selection *sel = arg;
307
308 if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
309 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
310 return -EINVAL;
311
312 if (sel->pad >= sd->entity.num_pads)
313 return -EINVAL;
314
315 return v4l2_subdev_call(
316 sd, pad, set_selection, subdev_fh, sel);
317 }
296#endif 318#endif
297 default: 319 default:
298 return v4l2_subdev_call(sd, core, ioctl, cmd, arg); 320 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index ed29cbbebfef..812019ee1e06 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -123,6 +123,43 @@ struct v4l2_subdev_frame_interval_enum {
123 __u32 reserved[9]; 123 __u32 reserved[9];
124}; 124};
125 125
126#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE (1 << 0)
127#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE (1 << 1)
128#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG (1 << 2)
129
130/* active cropping area */
131#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL 0x0000
132/* cropping bounds */
133#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS 0x0002
134/* current composing area */
135#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL 0x0100
136/* composing bounds */
137#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS 0x0102
138
139
140/**
141 * struct v4l2_subdev_selection - selection info
142 *
143 * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY
144 * @pad: pad number, as reported by the media API
145 * @target: selection target, used to choose one of possible rectangles
146 * @flags: constraint flags
147 * @r: coordinates of the selection window
148 * @reserved: for future use, set to zero for now
149 *
150 * Hardware may use multiple helper windows to process a video stream.
151 * The structure is used to exchange this selection areas between
152 * an application and a driver.
153 */
154struct v4l2_subdev_selection {
155 __u32 which;
156 __u32 pad;
157 __u32 target;
158 __u32 flags;
159 struct v4l2_rect r;
160 __u32 reserved[8];
161};
162
126#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) 163#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
127#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) 164#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
128#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \ 165#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
@@ -137,5 +174,9 @@ struct v4l2_subdev_frame_interval_enum {
137 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) 174 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
138#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) 175#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
139#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) 176#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
177#define VIDIOC_SUBDEV_G_SELECTION \
178 _IOWR('V', 61, struct v4l2_subdev_selection)
179#define VIDIOC_SUBDEV_S_SELECTION \
180 _IOWR('V', 62, struct v4l2_subdev_selection)
140 181
141#endif 182#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index f0f3358d1b1b..feab950bc8ab 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -466,6 +466,10 @@ struct v4l2_subdev_pad_ops {
466 struct v4l2_subdev_crop *crop); 466 struct v4l2_subdev_crop *crop);
467 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 467 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
468 struct v4l2_subdev_crop *crop); 468 struct v4l2_subdev_crop *crop);
469 int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
470 struct v4l2_subdev_selection *sel);
471 int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
472 struct v4l2_subdev_selection *sel);
469}; 473};
470 474
471struct v4l2_subdev_ops { 475struct v4l2_subdev_ops {
@@ -549,8 +553,11 @@ struct v4l2_subdev {
549struct v4l2_subdev_fh { 553struct v4l2_subdev_fh {
550 struct v4l2_fh vfh; 554 struct v4l2_fh vfh;
551#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 555#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
552 struct v4l2_mbus_framefmt *try_fmt; 556 struct {
553 struct v4l2_rect *try_crop; 557 struct v4l2_mbus_framefmt try_fmt;
558 struct v4l2_rect try_crop;
559 struct v4l2_rect try_compose;
560 } *pad;
554#endif 561#endif
555}; 562};
556 563
@@ -561,13 +568,19 @@ struct v4l2_subdev_fh {
561static inline struct v4l2_mbus_framefmt * 568static inline struct v4l2_mbus_framefmt *
562v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad) 569v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
563{ 570{
564 return &fh->try_fmt[pad]; 571 return &fh->pad[pad].try_fmt;
565} 572}
566 573
567static inline struct v4l2_rect * 574static inline struct v4l2_rect *
568v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad) 575v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
569{ 576{
570 return &fh->try_crop[pad]; 577 return &fh->pad[pad].try_crop;
578}
579
580static inline struct v4l2_rect *
581v4l2_subdev_get_try_compose(struct v4l2_subdev_fh *fh, unsigned int pad)
582{
583 return &fh->pad[pad].try_compose;
571} 584}
572#endif 585#endif
573 586