[media] s5p-fimc: Fix vidioc_g_crop/cropcap on camera sensor

Create separate vidioc_g_crop/vidioc_s_crop handlers for capture
video node and so image cropping parameters are properly queried
at FIMC input (image sensor) and not at FIMC output.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by Sylwester Nawrocki and committed by Mauro Carvalho Chehab e004e02f 09b693f0

+59 -19
+46 -2
drivers/media/video/s5p-fimc/fimc-capture.c
··· 652 return ret; 653 } 654 655 static int fimc_cap_s_crop(struct file *file, void *fh, 656 struct v4l2_crop *cr) 657 { ··· 760 .vidioc_g_ctrl = fimc_vidioc_g_ctrl, 761 .vidioc_s_ctrl = fimc_cap_s_ctrl, 762 763 - .vidioc_g_crop = fimc_vidioc_g_crop, 764 .vidioc_s_crop = fimc_cap_s_crop, 765 - .vidioc_cropcap = fimc_vidioc_cropcap, 766 767 .vidioc_enum_input = fimc_cap_enum_input, 768 .vidioc_s_input = fimc_cap_s_input,
··· 652 return ret; 653 } 654 655 + static int fimc_cap_cropcap(struct file *file, void *fh, 656 + struct v4l2_cropcap *cr) 657 + { 658 + struct fimc_frame *f; 659 + struct fimc_ctx *ctx = fh; 660 + struct fimc_dev *fimc = ctx->fimc_dev; 661 + 662 + if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 663 + return -EINVAL; 664 + 665 + if (mutex_lock_interruptible(&fimc->lock)) 666 + return -ERESTARTSYS; 667 + 668 + f = &ctx->s_frame; 669 + cr->bounds.left = 0; 670 + cr->bounds.top = 0; 671 + cr->bounds.width = f->o_width; 672 + cr->bounds.height = f->o_height; 673 + cr->defrect = cr->bounds; 674 + 675 + mutex_unlock(&fimc->lock); 676 + return 0; 677 + } 678 + 679 + static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 680 + { 681 + struct fimc_frame *f; 682 + struct fimc_ctx *ctx = file->private_data; 683 + struct fimc_dev *fimc = ctx->fimc_dev; 684 + 685 + 686 + if (mutex_lock_interruptible(&fimc->lock)) 687 + return -ERESTARTSYS; 688 + 689 + f = &ctx->s_frame; 690 + cr->c.left = f->offs_h; 691 + cr->c.top = f->offs_v; 692 + cr->c.width = f->width; 693 + cr->c.height = f->height; 694 + 695 + mutex_unlock(&fimc->lock); 696 + return 0; 697 + } 698 + 699 static int fimc_cap_s_crop(struct file *file, void *fh, 700 struct v4l2_crop *cr) 701 { ··· 716 .vidioc_g_ctrl = fimc_vidioc_g_ctrl, 717 .vidioc_s_ctrl = fimc_cap_s_ctrl, 718 719 + .vidioc_g_crop = fimc_cap_g_crop, 720 .vidioc_s_crop = fimc_cap_s_crop, 721 + .vidioc_cropcap = fimc_cap_cropcap, 722 723 .vidioc_enum_input = fimc_cap_enum_input, 724 .vidioc_s_input = fimc_cap_s_input,
+13 -13
drivers/media/video/s5p-fimc/fimc-core.c
··· 1115 return 0; 1116 } 1117 1118 - int fimc_vidioc_cropcap(struct file *file, void *fh, 1119 struct v4l2_cropcap *cr) 1120 { 1121 struct fimc_frame *frame; ··· 1139 return 0; 1140 } 1141 1142 - int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1143 { 1144 struct fimc_frame *frame; 1145 struct fimc_ctx *ctx = file->private_data; ··· 1167 struct fimc_frame *f; 1168 u32 min_size, halign; 1169 1170 - f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? 1171 - &ctx->s_frame : &ctx->d_frame; 1172 - 1173 if (cr->c.top < 0 || cr->c.left < 0) { 1174 v4l2_err(&fimc->m2m.v4l2_dev, 1175 "doesn't support negative values for top & left\n"); 1176 return -EINVAL; 1177 } 1178 1179 - f = ctx_get_frame(ctx, cr->type); 1180 - if (IS_ERR(f)) 1181 - return PTR_ERR(f); 1182 1183 - min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 1184 - ? fimc->variant->min_inp_pixsize 1185 - : fimc->variant->min_out_pixsize; 1186 1187 if (ctx->state & FIMC_CTX_M2M) { 1188 if (fimc->id == 1 && fimc->variant->pix_hoff) ··· 1285 .vidioc_g_ctrl = fimc_vidioc_g_ctrl, 1286 .vidioc_s_ctrl = fimc_m2m_s_ctrl, 1287 1288 - .vidioc_g_crop = fimc_vidioc_g_crop, 1289 .vidioc_s_crop = fimc_m2m_s_crop, 1290 - .vidioc_cropcap = fimc_vidioc_cropcap 1291 1292 }; 1293
··· 1115 return 0; 1116 } 1117 1118 + static int fimc_m2m_cropcap(struct file *file, void *fh, 1119 struct v4l2_cropcap *cr) 1120 { 1121 struct fimc_frame *frame; ··· 1139 return 0; 1140 } 1141 1142 + static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1143 { 1144 struct fimc_frame *frame; 1145 struct fimc_ctx *ctx = file->private_data; ··· 1167 struct fimc_frame *f; 1168 u32 min_size, halign; 1169 1170 if (cr->c.top < 0 || cr->c.left < 0) { 1171 v4l2_err(&fimc->m2m.v4l2_dev, 1172 "doesn't support negative values for top & left\n"); 1173 return -EINVAL; 1174 } 1175 1176 + if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1177 + f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame; 1178 + else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 1179 + ctx->state & FIMC_CTX_M2M) 1180 + f = &ctx->s_frame; 1181 + else 1182 + return -EINVAL; 1183 1184 + min_size = (f == &ctx->s_frame) ? 1185 + fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; 1186 1187 if (ctx->state & FIMC_CTX_M2M) { 1188 if (fimc->id == 1 && fimc->variant->pix_hoff) ··· 1285 .vidioc_g_ctrl = fimc_vidioc_g_ctrl, 1286 .vidioc_s_ctrl = fimc_m2m_s_ctrl, 1287 1288 + .vidioc_g_crop = fimc_m2m_g_crop, 1289 .vidioc_s_crop = fimc_m2m_s_crop, 1290 + .vidioc_cropcap = fimc_m2m_cropcap 1291 1292 }; 1293
-4
drivers/media/video/s5p-fimc/fimc-core.h
··· 594 struct v4l2_format *f); 595 int fimc_vidioc_try_fmt(struct file *file, void *priv, 596 struct v4l2_format *f); 597 - int fimc_vidioc_g_crop(struct file *file, void *fh, 598 - struct v4l2_crop *cr); 599 - int fimc_vidioc_cropcap(struct file *file, void *fh, 600 - struct v4l2_cropcap *cr); 601 int fimc_vidioc_queryctrl(struct file *file, void *priv, 602 struct v4l2_queryctrl *qc); 603 int fimc_vidioc_g_ctrl(struct file *file, void *priv,
··· 594 struct v4l2_format *f); 595 int fimc_vidioc_try_fmt(struct file *file, void *priv, 596 struct v4l2_format *f); 597 int fimc_vidioc_queryctrl(struct file *file, void *priv, 598 struct v4l2_queryctrl *qc); 599 int fimc_vidioc_g_ctrl(struct file *file, void *priv,