From patchwork Wed Jul 14 14:07:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 112004 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6EE6fJr010560 for ; Wed, 14 Jul 2010 14:06:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757027Ab0GNOGO (ORCPT ); Wed, 14 Jul 2010 10:06:14 -0400 Received: from perceval.irobotique.be ([92.243.18.41]:52764 "EHLO perceval.irobotique.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756968Ab0GNOGK (ORCPT ); Wed, 14 Jul 2010 10:06:10 -0400 Received: from localhost.localdomain (unknown [91.178.183.65]) by perceval.irobotique.be (Postfix) with ESMTPSA id 118CA35FEB; Wed, 14 Jul 2010 14:06:05 +0000 (UTC) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: sakari.ailus@maxwell.research.nokia.com Subject: [SAMPLE 07/12] v4l: Add crop ioctl to V4L2 subdev API Date: Wed, 14 Jul 2010 16:07:09 +0200 Message-Id: <1279116434-28278-8-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1279114219-27389-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1279114219-27389-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 14 Jul 2010 14:06:44 +0000 (UTC) diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c index 8ddb2fb..ad4b95e 100644 --- a/drivers/media/video/v4l2-subdev.c +++ b/drivers/media/video/v4l2-subdev.c @@ -30,11 +30,16 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) { - fh->probe_fmt = kzalloc(sizeof(*fh->probe_fmt) * - sd->entity.num_pads, GFP_KERNEL); + /* Allocate probe format and crop in the same memory block */ + fh->probe_fmt = kzalloc((sizeof(*fh->probe_fmt) + + sizeof(*fh->probe_crop)) * sd->entity.num_pads, + GFP_KERNEL); if (fh->probe_fmt == NULL) return -ENOMEM; + fh->probe_crop = (struct v4l2_rect *) + (fh->probe_fmt + sd->entity.num_pads); + return 0; } @@ -42,6 +47,7 @@ static void subdev_fh_free(struct v4l2_subdev_fh *fh) { kfree(fh->probe_fmt); fh->probe_fmt = NULL; + fh->probe_crop = NULL; } static int subdev_open(struct file *file) @@ -188,6 +194,32 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) format->which); } + case VIDIOC_SUBDEV_G_CROP: { + struct v4l2_subdev_pad_crop *crop = arg; + + if (crop->which != V4L2_SUBDEV_FORMAT_PROBE && + crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + if (crop->pad >= sd->entity.num_pads) + return -EINVAL; + + return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop); + } + + case VIDIOC_SUBDEV_S_CROP: { + struct v4l2_subdev_pad_crop *crop = arg; + + if (crop->which != V4L2_SUBDEV_FORMAT_PROBE && + crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + + if (crop->pad >= sd->entity.num_pads) + return -EINVAL; + + return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop); + } + case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { struct v4l2_subdev_pad_mbus_code_enum *code = arg; diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h index e3362aa..5738e81 100644 --- a/include/linux/v4l2-subdev.h +++ b/include/linux/v4l2-subdev.h @@ -36,6 +36,16 @@ struct v4l2_subdev_pad_format { }; /** + * struct v4l2_subdev_pad_crop + */ +struct v4l2_subdev_pad_crop { + __u32 pad; + __u32 which; + struct v4l2_rect rect; + __u32 reserved[10]; +}; + +/** * struct v4l2_subdev_pad_mbus_code_enum */ struct v4l2_subdev_pad_mbus_code_enum { @@ -86,5 +96,7 @@ struct v4l2_subdev_frame_interval_enum { _IOWR('V', 9, struct v4l2_subdev_frame_size_enum) #define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \ _IOWR('V', 10, struct v4l2_subdev_frame_interval_enum) +#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 11, struct v4l2_subdev_pad_crop) +#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 12, struct v4l2_subdev_pad_crop) #endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 58ef923..41183ab 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -419,6 +419,10 @@ struct v4l2_subdev_pad_ops { int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format which); + int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_pad_crop *crop); + int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_pad_crop *crop); }; struct v4l2_subdev_ops { @@ -478,6 +482,7 @@ struct v4l2_subdev { struct v4l2_subdev_fh { struct v4l2_fh vfh; struct v4l2_mbus_framefmt *probe_fmt; + struct v4l2_rect *probe_crop; }; #define to_v4l2_subdev_fh(fh) \ @@ -489,6 +494,12 @@ v4l2_subdev_get_probe_format(struct v4l2_subdev_fh *fh, unsigned int pad) return &fh->probe_fmt[pad]; } +static inline struct v4l2_rect * +v4l2_subdev_get_probe_crop(struct v4l2_subdev_fh *fh, unsigned int pad) +{ + return &fh->probe_crop[pad]; +} + extern const struct v4l2_file_operations v4l2_subdev_fops; static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)