diff options
Diffstat (limited to 'drivers/staging/media')
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_cmd.c | 6 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_internal.h | 7 | ||||
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp_v4l2.c | 55 |
3 files changed, 64 insertions, 4 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index e17d057f8867..4564b9ad7223 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -3698,9 +3698,8 @@ int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f, const struct atomisp_format_bridge *fmt, *snr_fmt; struct atomisp_sub_device *asd = &isp->asd; struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; - struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg, + .pads = &input->pad_cfg, }; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_TRY, @@ -4164,9 +4163,8 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, const struct v4l2_p struct atomisp_device *isp = asd->isp; struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; const struct atomisp_format_bridge *format; - struct v4l2_subdev_pad_config pad_cfg; struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg, + .pads = &input->pad_cfg, }; struct v4l2_subdev_format vformat = { .which = V4L2_SUBDEV_FORMAT_TRY, diff --git a/drivers/staging/media/atomisp/pci/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp_internal.h index e59c0f1e7f53..14d21c6e227d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_internal.h +++ b/drivers/staging/media/atomisp/pci/atomisp_internal.h @@ -125,7 +125,14 @@ struct atomisp_input_subdev { unsigned int type; enum atomisp_camera_port port; + bool crop_support; struct v4l2_subdev *camera; + /* Sensor rects for sensors which support crop */ + struct v4l2_rect native_rect; + struct v4l2_rect active_rect; + /* Sensor pad_cfg for which == V4L2_SUBDEV_FORMAT_TRY calls */ + struct v4l2_subdev_pad_config pad_cfg; + struct v4l2_subdev *motor; /* diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index a2ce9bbf10df..506f04ca92b1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -931,6 +931,59 @@ v4l2_device_failed: return ret; } +static void atomisp_init_sensor(struct atomisp_input_subdev *input) +{ + struct v4l2_subdev_state sd_state = { + .pads = &input->pad_cfg, + }; + struct v4l2_subdev_selection sel = { }; + int err; + + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.target = V4L2_SEL_TGT_NATIVE_SIZE; + err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel); + if (err) + return; + + input->native_rect = sel.r; + + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.target = V4L2_SEL_TGT_CROP_DEFAULT; + err = v4l2_subdev_call(input->camera, pad, get_selection, NULL, &sel); + if (err) + return; + + input->active_rect = sel.r; + + /* + * The ISP also wants the non-active pixels at the border of the sensor + * for padding, set the crop rect to cover the entire sensor instead + * of only the default active area. + * + * Do this for both try and active formats since the try_crop rect in + * pad_cfg may influence (clamp) future try_fmt calls with which == try. + */ + sel.which = V4L2_SUBDEV_FORMAT_TRY; + sel.target = V4L2_SEL_TGT_CROP; + sel.r = input->native_rect; + err = v4l2_subdev_call(input->camera, pad, set_selection, &sd_state, &sel); + if (err) + return; + + sel.which = V4L2_SUBDEV_FORMAT_ACTIVE; + sel.target = V4L2_SEL_TGT_CROP; + sel.r = input->native_rect; + err = v4l2_subdev_call(input->camera, pad, set_selection, NULL, &sel); + if (err) + return; + + dev_info(input->camera->dev, "Supports crop native %dx%d active %dx%d\n", + input->native_rect.width, input->native_rect.height, + input->active_rect.width, input->active_rect.height); + + input->crop_support = true; +} + int atomisp_register_device_nodes(struct atomisp_device *isp) { struct atomisp_input_subdev *input; @@ -952,6 +1005,8 @@ int atomisp_register_device_nodes(struct atomisp_device *isp) input->port = i; input->camera = isp->sensor_subdevs[i]; + atomisp_init_sensor(input); + /* * HACK: Currently VCM belongs to primary sensor only, but correct * approach must be to acquire from platform code which sensor |