media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Sun, 26 Nov 2023 02:09:48 +0000 (03:09 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Sat, 9 Dec 2023 06:47:10 +0000 (07:47 +0100)
Supported media bus codes on the resizer sink pad are identical to the
ISP source pad. The .enum_mbus_code() handler thus delegates the
enumeration to the ISP's operation. This is problematic for two
reasons:

- Format enumeration on the ISP source pad is dependent on the format
  configured on the ISP sink pad for the same subdev state (TRY or
  ACTIVE), while format enumeration on the resizer sink pad should
  return all formats supported by the resizer subdev, regardless of the
  ISP configuration.

- Delegating the operation involves creating a fake v4l2_subdev_state on
  the stack to pass to the ISP .enum_mbus_code() handler. This gets in
  the way of evolution of both the ISP enumeration handler and, more
  generally, the V4L2 subdev state infrastructure.

Fix those two issues by implementing format enumeration manually for the
resizer.

Link: https://lore.kernel.org/r/20231126020948.2700-1-laurent.pinchart@ideasonboard.com
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c

index f7af360dcb28957ac3104c930bb13b69b35240b7..a8e3777013023ee4e79a6243b943d9079088474b 100644 (file)
@@ -330,12 +330,8 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
 {
        struct rkisp1_resizer *rsz =
                container_of(sd, struct rkisp1_resizer, sd);
-       struct v4l2_subdev_pad_config dummy_cfg;
-       struct v4l2_subdev_state pad_state = {
-               .pads = &dummy_cfg
-       };
-       u32 pad = code->pad;
-       int ret;
+       unsigned int index = code->index;
+       unsigned int i;
 
        if (code->pad == RKISP1_RSZ_PAD_SRC) {
                /* supported mbus codes on the src are the same as in the capture */
@@ -355,15 +351,29 @@ static int rkisp1_rsz_enum_mbus_code(struct v4l2_subdev *sd,
                return 0;
        }
 
-       /* supported mbus codes on the sink pad are the same as isp src pad */
-       code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO;
-       ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code,
-                              &pad_state, code);
+       /*
+        * Supported mbus codes on the sink pad are the same as on the ISP
+        * source pad.
+        */
+       for (i = 0; ; i++) {
+               const struct rkisp1_mbus_info *fmt =
+                       rkisp1_mbus_info_get_by_index(i);
 
-       /* restore pad */
-       code->pad = pad;
-       code->flags = 0;
-       return ret;
+               if (!fmt)
+                       break;
+
+               if (!(fmt->direction & RKISP1_ISP_SD_SRC))
+                       continue;
+
+               if (!index) {
+                       code->code = fmt->mbus_code;
+                       return 0;
+               }
+
+               index--;
+       }
+
+       return -EINVAL;
 }
 
 static int rkisp1_rsz_init_state(struct v4l2_subdev *sd,