static int gsc_capture_subdev_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_crop *crop) { struct gsc_dev *gsc = v4l2_get_subdevdata(sd); struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame = gsc_capture_get_frame(ctx, crop->pad); gsc_cap_try_crop(gsc, &crop->rect, crop->pad); if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) frame->crop = crop->rect; return 0; }
static void gsc_cap_try_crop(struct gsc_dev *gsc, struct v4l2_rect *crop, u32 pad) { struct gsc_variant *variant = gsc->variant; struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame = gsc_capture_get_frame(ctx, pad); u32 crop_min_w = variant->pix_min->target_w; u32 crop_min_h = variant->pix_min->target_h; u32 crop_max_w = frame->f_width; u32 crop_max_h = frame->f_height; crop->left = clamp_t(u32, crop->left, 0, crop_max_w - crop_min_w); crop->top = clamp_t(u32, crop->top, 0, crop_max_h - crop_min_h); crop->width = clamp_t(u32, crop->width, crop_min_w, crop_max_w); crop->height = clamp_t(u32, crop->height, crop_min_h, crop_max_h); }
static int __gsc_cap_get_crop(struct gsc_dev *gsc, struct v4l2_subdev_fh *fh, unsigned int pad, enum v4l2_subdev_format_whence which, struct v4l2_rect *crop) { struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame = gsc_capture_get_frame(ctx, pad); if (which == V4L2_SUBDEV_FORMAT_TRY) { crop = v4l2_subdev_get_try_crop(fh, pad); } else { crop->left = frame->crop.left; crop->top = frame->crop.top; crop->width = frame->crop.width; crop->height = frame->crop.height; } return 0; }
static int gsc_capture_subdev_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_crop *crop) { struct gsc_dev *gsc = v4l2_get_subdevdata(sd); struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame = gsc_capture_get_frame(ctx, crop->pad); if ((crop->pad == GSC_PAD_SINK) && (crop->rect.width % 8)) { gsc_err("%d is not aligned 8", crop->rect.width); return -EINVAL; } gsc_cap_try_crop(gsc, &crop->rect, crop->pad); if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) frame->crop = crop->rect; return 0; }
static int gsc_capture_subdev_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) { struct gsc_dev *gsc = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf; struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame; mf = __gsc_cap_get_format(gsc, fh, fmt->pad, fmt->which); if (mf == NULL) return -EINVAL; gsc_cap_try_format(gsc, fh, fmt->pad, &fmt->format, fmt->which); *mf = fmt->format; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) return 0; frame = gsc_capture_get_frame(ctx, fmt->pad); if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { frame->crop.left = 0; frame->crop.top = 0; frame->f_width = mf->width; frame->f_height = mf->height; frame->crop.width = mf->width; frame->crop.height = mf->height; } gsc_dbg("offs_h : %d, offs_v : %d, f_width : %d, f_height :%d,\ width : %d, height : %d", frame->crop.left,\ frame->crop.top, frame->f_width, frame->f_height,\ frame->crop.width, frame->crop.height); return 0; }