summaryrefslogtreecommitdiff
path: root/drivers/staging/media/atomisp/pci/atomisp_v4l2.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2023-05-29 13:37:35 +0300
committerMauro Carvalho Chehab <mchehab@kernel.org>2023-06-09 17:31:38 +0300
commit04eca831605390071be83b87774e4987639e6331 (patch)
tree91c4fc2049d5720dc7b845aecae6f82f5c5d6d82 /drivers/staging/media/atomisp/pci/atomisp_v4l2.c
parent929eee2fb07aee951c493cfdd87cb19719606d91 (diff)
downloadlinux-04eca831605390071be83b87774e4987639e6331.tar.xz
media: atomisp: Add support for sensors which implement selection API / cropping
Sensor drivers which implement set_selection V4L2_SEL_TGT_CROP expect v4l2_subdev_state.pads[pad].try_crop to have valid contents when calling set_fmt with which == V4L2_SUBDEV_FORMAT_TRY since the crop-rectangle may influence the available image size. Just passing an uninitalized struct v4l2_subdev_pad_config from the stack to set_fmt with which == V4L2_SUBDEV_FORMAT_TRY will result in wrong results with such drivers. Store a per sensor v4l2_subdev_pad_config and add a new atomisp_init_sensor_crop() function to initialize this before registering /dev/* nodes with userspace. Sensor drivers which implement the selection API will allow the atomisp to properly deal with the extra padding the ISP wants on a per sensor basis instead of hardcoding this. atomisp_init_sensor_crop() stores the native and active rects of the sensor in preparation for using these for this. Link: https://lore.kernel.org/r/20230529103741.11904-16-hdegoede@redhat.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/staging/media/atomisp/pci/atomisp_v4l2.c')
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_v4l2.c55
1 files changed, 55 insertions, 0 deletions
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