diff options
-rw-r--r-- | drivers/media/video/v4l2-subdev.c | 42 | ||||
-rw-r--r-- | include/linux/v4l2-subdev.h | 41 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 21 |
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 @@ | |||
35 | static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) | 35 | static 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) | |||
50 | static void subdev_fh_free(struct v4l2_subdev_fh *fh) | 45 | static 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 | */ | ||
154 | struct 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 | ||
471 | struct v4l2_subdev_ops { | 475 | struct v4l2_subdev_ops { |
@@ -549,8 +553,11 @@ struct v4l2_subdev { | |||
549 | struct v4l2_subdev_fh { | 553 | struct 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 { | |||
561 | static inline struct v4l2_mbus_framefmt * | 568 | static inline struct v4l2_mbus_framefmt * |
562 | v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad) | 569 | v4l2_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 | ||
567 | static inline struct v4l2_rect * | 574 | static inline struct v4l2_rect * |
568 | v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad) | 575 | v4l2_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 | |||
580 | static inline struct v4l2_rect * | ||
581 | v4l2_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 | ||