diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 22:39:09 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 22:39:09 +0100 |
commit | e317234975cb7463b8ca21a93bb6862d9dcf113f (patch) | |
tree | 4446fa3a21364f3cba23a22aa2a94027f169d8df /drivers/media/video/s5p-fimc/fimc-capture.c | |
parent | Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff) | |
parent | Merge branch 'staging/for_v3.4' into v4l_for_linus (diff) | |
download | linux-e317234975cb7463b8ca21a93bb6862d9dcf113f.tar.xz linux-e317234975cb7463b8ca21a93bb6862d9dcf113f.zip |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- V4L2 API additions to better support JPEG compression control
- media API additions to properly support MPEG decoders
- V4L2 API additions for image crop/scaling
- a few other V4L2 API DocBook fixes/improvements
- two new DVB frontend drivers: m88rs2000 and rtl2830
- two new DVB drivers: az6007 and rtl28xxu
- a framework for ISA drivers, that removed lots of common code found
at the ISA radio drivers
- a new FM transmitter driver (radio-keene)
- a GPIO-based IR receiver driver
- a new sensor driver: mt9m032
- some new video drivers: adv7183, blackfin, mx2_emmaprp, sii9234_drv,
vs6624
- several new board additions, driver fixes, improvements and cleanups.
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (295 commits)
[media] update CARDLIST.em28xx
[media] partially reverts changeset fa5527c
[media] stb0899: fix the limits for signal strength values
[media] em28xx: support for 2304:0242 PCTV QuatroStick (510e)
[media] em28xx: support for 2013:0251 PCTV QuatroStick nano (520e)
[media] -EINVAL -> -ENOTTY
[media] gspca - sn9c20x: Cleanup source
[media] gspca - sn9c20x: Simplify register write for capture start/stop
[media] gspca - sn9c20x: Add automatic JPEG compression mechanism
[media] gspca - sn9c20x: Greater delay in case of sensor no response
[media] gspca - sn9c20x: Optimize the code of write sequences
[media] gspca - sn9c20x: Add the JPEG compression quality control
[media] gspca - sn9c20x: Add a delay after Omnivision sensor reset
[media] gspca - sn9c20x: Propagate USB errors to higher level
[media] gspca - sn9c20x: Use the new video control mechanism
[media] gspca - sn9c20x: Fix loss of frame start
[media] gspca - zc3xx: Lack of register 08 value for sensor cs2102k
[media] gspca - ov534_9: Add brightness to OmniVision 5621 sensor
[media] gspca - zc3xx: Add V4L2_CID_JPEG_COMPRESSION_QUALITY control support
[media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5
...
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-capture.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 121 |
1 files changed, 94 insertions, 27 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index a9e9653beeb4..b06efd208328 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -1019,52 +1019,117 @@ static int fimc_cap_dqbuf(struct file *file, void *priv, return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK); } -static int fimc_cap_cropcap(struct file *file, void *fh, - struct v4l2_cropcap *cr) +static int fimc_cap_create_bufs(struct file *file, void *priv, + struct v4l2_create_buffers *create) { struct fimc_dev *fimc = video_drvdata(file); - struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; - if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; + return vb2_create_bufs(&fimc->vid_cap.vbq, create); +} - cr->bounds.left = 0; - cr->bounds.top = 0; - cr->bounds.width = f->o_width; - cr->bounds.height = f->o_height; - cr->defrect = cr->bounds; +static int fimc_cap_prepare_buf(struct file *file, void *priv, + struct v4l2_buffer *b) +{ + struct fimc_dev *fimc = video_drvdata(file); - return 0; + return vb2_prepare_buf(&fimc->vid_cap.vbq, b); } -static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) +static int fimc_cap_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) { struct fimc_dev *fimc = video_drvdata(file); - struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; + struct fimc_ctx *ctx = fimc->vid_cap.ctx; + struct fimc_frame *f = &ctx->s_frame; - cr->c.left = f->offs_h; - cr->c.top = f->offs_v; - cr->c.width = f->width; - cr->c.height = f->height; + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; - return 0; + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + f = &ctx->d_frame; + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + s->r.left = 0; + s->r.top = 0; + s->r.width = f->o_width; + s->r.height = f->o_height; + return 0; + + case V4L2_SEL_TGT_COMPOSE_ACTIVE: + f = &ctx->d_frame; + case V4L2_SEL_TGT_CROP_ACTIVE: + s->r.left = f->offs_h; + s->r.top = f->offs_v; + s->r.width = f->width; + s->r.height = f->height; + return 0; + } + + return -EINVAL; } -static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) +/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ +int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) +{ + if (a->left < b->left || a->top < b->top) + return 0; + if (a->left + a->width > b->left + b->width) + return 0; + if (a->top + a->height > b->top + b->height) + return 0; + + return 1; +} + +static int fimc_cap_s_selection(struct file *file, void *fh, + struct v4l2_selection *s) { struct fimc_dev *fimc = video_drvdata(file); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - struct fimc_frame *ff; + struct v4l2_rect rect = s->r; + struct fimc_frame *f; unsigned long flags; + unsigned int pad; - fimc_capture_try_crop(ctx, &cr->c, FIMC_SD_PAD_SINK); - ff = &ctx->s_frame; + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SEL_TGT_COMPOSE_ACTIVE: + f = &ctx->d_frame; + pad = FIMC_SD_PAD_SOURCE; + break; + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_ACTIVE: + f = &ctx->s_frame; + pad = FIMC_SD_PAD_SINK; + break; + default: + return -EINVAL; + } + + fimc_capture_try_crop(ctx, &rect, pad); + + if (s->flags & V4L2_SEL_FLAG_LE && + !enclosed_rectangle(&rect, &s->r)) + return -ERANGE; + + if (s->flags & V4L2_SEL_FLAG_GE && + !enclosed_rectangle(&s->r, &rect)) + return -ERANGE; + + s->r = rect; spin_lock_irqsave(&fimc->slock, flags); - set_frame_crop(ff, cr->c.left, cr->c.top, cr->c.width, cr->c.height); - set_bit(ST_CAPT_APPLY_CFG, &fimc->state); + set_frame_crop(f, s->r.left, s->r.top, s->r.width, + s->r.height); spin_unlock_irqrestore(&fimc->slock, flags); + set_bit(ST_CAPT_APPLY_CFG, &fimc->state); return 0; } @@ -1082,12 +1147,14 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { .vidioc_qbuf = fimc_cap_qbuf, .vidioc_dqbuf = fimc_cap_dqbuf, + .vidioc_prepare_buf = fimc_cap_prepare_buf, + .vidioc_create_bufs = fimc_cap_create_bufs, + .vidioc_streamon = fimc_cap_streamon, .vidioc_streamoff = fimc_cap_streamoff, - .vidioc_g_crop = fimc_cap_g_crop, - .vidioc_s_crop = fimc_cap_s_crop, - .vidioc_cropcap = fimc_cap_cropcap, + .vidioc_g_selection = fimc_cap_g_selection, + .vidioc_s_selection = fimc_cap_s_selection, .vidioc_enum_input = fimc_cap_enum_input, .vidioc_s_input = fimc_cap_s_input, |