diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 10:21:51 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-24 10:21:51 -0700 |
commit | ab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (patch) | |
tree | 987ec6c263f3dfa4a7a6f9ce4d5ece47cbc12e29 /drivers/media/video/omap3isp/ispresizer.c | |
parent | f9369910a6225b8d4892c3f20ae740a711cd5ace (diff) | |
parent | 71006fb22b0f5a2045605b3887ee99a0e9adafe4 (diff) |
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:
- some V4L2 API updates needed by embedded devices
- DVB API extensions for ATSC-MH delivery system, used in US for mobile
TV
- new tuners for fc0011/0012/0013 and tua9001
- a new dvb driver for af9033/9035
- a new ATSC-MH frontend (lg2160)
- new remote controller keymaps
- Removal of a few legacy webcam driver that got replaced by gspca on
several kernel versions ago
- a new driver for Exynos 4/5 webcams(s5pp fimc-lite)
- a new webcam sensor driver (smiapp)
- a new video input driver for embedded (sta2x1xx)
- several improvements, fixes, cleanups, etc inside the drivers.
Manually fix up conflicts due to err() -> dev_err() conversion in
drivers/staging/media/easycap/easycap_main.c
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (484 commits)
[media] saa7134-cards: Remove a PCI entry added by mistake
[media] radio-sf16fmi: add support for SF16-FMD
[media] rc-loopback: remove duplicate line
[media] patch for Asus My Cinema PS3-100 (1043:48cd)
[media] au0828: Move the Kconfig knob under V4L_USB_DRIVERS
[media] em28xx: simple comment fix
[media] [resend] radio-sf16fmr2: add PnP support for SF16-FMD2
[media] smiapp: Use v4l2_ctrl_new_int_menu() instead of v4l2_ctrl_new_custom()
[media] smiapp: Add support for 8-bit uncompressed formats
[media] smiapp: Allow generic quirk registers
[media] smiapp: Use non-binning limits if the binning limit is zero
[media] smiapp: Initialise rval in smiapp_read_nvm()
[media] smiapp: Round minimum pre_pll up rather than down in ip_clk_freq check
[media] smiapp: Use 8-bit reads only before identifying the sensor
[media] smiapp: Quirk for sensors that only do 8-bit reads
[media] smiapp: Pass struct sensor to register writing commands instead of i2c_client
[media] smiapp: Allow using external clock from the clock framework
[media] zl10353: change .read_snr() to report SNR as a 0.1 dB
[media] media: add support to gspca/pac7302.c for 093a:2627 (Genius FaceCam 300)
[media] m88rs2000 - only flip bit 2 on reg 0x70 on 16th try
...
Diffstat (limited to 'drivers/media/video/omap3isp/ispresizer.c')
-rw-r--r-- | drivers/media/video/omap3isp/ispresizer.c | 139 |
1 files changed, 89 insertions, 50 deletions
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c index 6958a9e3dc2..14041c9c864 100644 --- a/drivers/media/video/omap3isp/ispresizer.c +++ b/drivers/media/video/omap3isp/ispresizer.c @@ -1188,32 +1188,6 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable) } /* - * resizer_g_crop - handle get crop subdev operation - * @sd : pointer to v4l2 subdev structure - * @pad : subdev pad - * @crop : pointer to crop structure - * @which : active or try format - * return zero - */ -static int resizer_g_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, - struct v4l2_subdev_crop *crop) -{ - struct isp_res_device *res = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *format; - struct resizer_ratio ratio; - - /* Only sink pad has crop capability */ - if (crop->pad != RESZ_PAD_SINK) - return -EINVAL; - - format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, crop->which); - crop->rect = *__resizer_get_crop(res, fh, crop->which); - resizer_calc_ratios(res, &crop->rect, format, &ratio); - - return 0; -} - -/* * resizer_try_crop - mangles crop parameters. */ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, @@ -1223,7 +1197,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, const unsigned int spv = DEFAULT_PHASE; const unsigned int sph = DEFAULT_PHASE; - /* Crop rectangle is constrained to the output size so that zoom ratio + /* Crop rectangle is constrained by the output size so that zoom ratio * cannot exceed +/-4.0. */ unsigned int min_width = @@ -1248,51 +1222,115 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, } /* - * resizer_s_crop - handle set crop subdev operation - * @sd : pointer to v4l2 subdev structure - * @pad : subdev pad - * @crop : pointer to crop structure - * @which : active or try format - * return -EINVAL or zero when succeed + * resizer_get_selection - Retrieve a selection rectangle on a pad + * @sd: ISP resizer V4L2 subdevice + * @fh: V4L2 subdev file handle + * @sel: Selection rectangle + * + * The only supported rectangles are the crop rectangles on the sink pad. + * + * Return 0 on success or a negative error code otherwise. */ -static int resizer_s_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, - struct v4l2_subdev_crop *crop) +static int resizer_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_selection *sel) +{ + struct isp_res_device *res = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *format_source; + struct v4l2_mbus_framefmt *format_sink; + struct resizer_ratio ratio; + + if (sel->pad != RESZ_PAD_SINK) + return -EINVAL; + + format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, + sel->which); + format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, + sel->which); + + switch (sel->target) { + case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = INT_MAX; + sel->r.height = INT_MAX; + + resizer_try_crop(format_sink, format_source, &sel->r); + resizer_calc_ratios(res, &sel->r, format_source, &ratio); + break; + + case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: + sel->r = *__resizer_get_crop(res, fh, sel->which); + resizer_calc_ratios(res, &sel->r, format_source, &ratio); + break; + + default: + return -EINVAL; + } + + return 0; +} + +/* + * resizer_set_selection - Set a selection rectangle on a pad + * @sd: ISP resizer V4L2 subdevice + * @fh: V4L2 subdev file handle + * @sel: Selection rectangle + * + * The only supported rectangle is the actual crop rectangle on the sink pad. + * + * FIXME: This function currently behaves as if the KEEP_CONFIG selection flag + * was always set. + * + * Return 0 on success or a negative error code otherwise. + */ +static int resizer_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_selection *sel) { struct isp_res_device *res = v4l2_get_subdevdata(sd); struct isp_device *isp = to_isp_device(res); struct v4l2_mbus_framefmt *format_sink, *format_source; struct resizer_ratio ratio; - /* Only sink pad has crop capability */ - if (crop->pad != RESZ_PAD_SINK) + if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL || + sel->pad != RESZ_PAD_SINK) return -EINVAL; format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, - crop->which); + sel->which); format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, - crop->which); + sel->which); dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__, - crop->rect.left, crop->rect.top, crop->rect.width, - crop->rect.height, crop->which); + sel->r.left, sel->r.top, sel->r.width, sel->r.height, + sel->which); dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__, format_sink->width, format_sink->height, format_source->width, format_source->height); - resizer_try_crop(format_sink, format_source, &crop->rect); - *__resizer_get_crop(res, fh, crop->which) = crop->rect; - resizer_calc_ratios(res, &crop->rect, format_source, &ratio); + /* Clamp the crop rectangle to the bounds, and then mangle it further to + * fulfill the TRM equations. Store the clamped but otherwise unmangled + * rectangle to avoid cropping the input multiple times: when an + * application sets the output format, the current crop rectangle is + * mangled during crop rectangle computation, which would lead to a new, + * smaller input crop rectangle every time the output size is set if we + * stored the mangled rectangle. + */ + resizer_try_crop(format_sink, format_source, &sel->r); + *__resizer_get_crop(res, fh, sel->which) = sel->r; + resizer_calc_ratios(res, &sel->r, format_source, &ratio); - if (crop->which == V4L2_SUBDEV_FORMAT_TRY) + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) return 0; res->ratio = ratio; - res->crop.active = crop->rect; + res->crop.active = sel->r; /* - * s_crop can be called while streaming is on. In this case - * the crop values will be set in the next IRQ. + * set_selection can be called while streaming is on. In this case the + * crop values will be set in the next IRQ. */ if (res->state != ISP_PIPELINE_STREAM_STOPPED) res->applycrop = 1; @@ -1530,8 +1568,8 @@ static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = { .enum_frame_size = resizer_enum_frame_size, .get_fmt = resizer_get_format, .set_fmt = resizer_set_format, - .get_crop = resizer_g_crop, - .set_crop = resizer_s_crop, + .get_selection = resizer_get_selection, + .set_selection = resizer_set_selection, }; /* subdev operations */ @@ -1603,6 +1641,7 @@ static int resizer_link_setup(struct media_entity *entity, /* media operations */ static const struct media_entity_operations resizer_media_ops = { .link_setup = resizer_link_setup, + .link_validate = v4l2_subdev_link_validate, }; void omap3isp_resizer_unregister_entities(struct isp_res_device *res) |