]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: adv748x-csi2: Use the subdev active state
authorJacopo Mondi <jacopo.mondi@ideasonboard.com>
Mon, 17 Jun 2024 16:11:31 +0000 (18:11 +0200)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 19 Jun 2024 16:43:04 +0000 (19:43 +0300)
Initialize and use the subdev active state to store the subdevice
format.

This simplifies the implementation of the get_fmt and set_fmt pad
operations.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Tested-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Link: https://lore.kernel.org/r/20240617161135.130719-9-jacopo.mondi@ideasonboard.com
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
drivers/media/i2c/adv748x/adv748x-csi2.c
drivers/media/i2c/adv748x/adv748x.h

index 0cdb397d9e0a5468e7ee0acc549a02b96cbb1c2d..ebe7da8ebed77377fb3f7b49d086b02767df5969 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/mutex.h>
 
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -68,7 +67,33 @@ static int adv748x_csi2_register_link(struct adv748x_csi2 *tx,
 
 /* -----------------------------------------------------------------------------
  * v4l2_subdev_internal_ops
- *
+ */
+
+static int adv748x_csi2_init_state(struct v4l2_subdev *sd,
+                                  struct v4l2_subdev_state *state)
+{
+       static const struct v4l2_mbus_framefmt adv748x_csi2_default_fmt = {
+               .width          = 1280,
+               .height         = 720,
+               .code           = MEDIA_BUS_FMT_UYVY8_1X16,
+               .colorspace     = V4L2_COLORSPACE_SRGB,
+               .field          = V4L2_FIELD_NONE,
+               .ycbcr_enc      = V4L2_YCBCR_ENC_DEFAULT,
+               .quantization   = V4L2_QUANTIZATION_DEFAULT,
+               .xfer_func      = V4L2_XFER_FUNC_DEFAULT,
+       };
+       struct v4l2_mbus_framefmt *fmt;
+
+       fmt = v4l2_subdev_state_get_format(state, ADV748X_CSI2_SINK);
+       *fmt = adv748x_csi2_default_fmt;
+
+       fmt = v4l2_subdev_state_get_format(state, ADV748X_CSI2_SOURCE);
+       *fmt = adv748x_csi2_default_fmt;
+
+       return 0;
+}
+
+/*
  * We use the internal registered operation to be able to ensure that our
  * incremental subdevices (not connected in the forward path) can be registered
  * against the resulting video path and media device.
@@ -118,6 +143,7 @@ static int adv748x_csi2_registered(struct v4l2_subdev *sd)
 }
 
 static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
+       .init_state = adv748x_csi2_init_state,
        .registered = adv748x_csi2_registered,
 };
 
@@ -183,41 +209,6 @@ static int adv748x_csi2_enum_mbus_code(struct v4l2_subdev *sd,
        return 0;
 }
 
-static struct v4l2_mbus_framefmt *
-adv748x_csi2_get_pad_format(struct v4l2_subdev *sd,
-                           struct v4l2_subdev_state *sd_state,
-                           unsigned int pad, u32 which)
-{
-       struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
-
-       if (which == V4L2_SUBDEV_FORMAT_TRY)
-               return v4l2_subdev_state_get_format(sd_state, pad);
-
-       return &tx->format;
-}
-
-static int adv748x_csi2_get_format(struct v4l2_subdev *sd,
-                                  struct v4l2_subdev_state *sd_state,
-                                  struct v4l2_subdev_format *sdformat)
-{
-       struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
-       struct adv748x_state *state = tx->state;
-       struct v4l2_mbus_framefmt *mbusformat;
-
-       mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad,
-                                                sdformat->which);
-       if (!mbusformat)
-               return -EINVAL;
-
-       mutex_lock(&state->mutex);
-
-       sdformat->format = *mbusformat;
-
-       mutex_unlock(&state->mutex);
-
-       return 0;
-}
-
 static bool adv748x_csi2_is_fmt_supported(struct adv748x_csi2 *tx, u32 code)
 {
        const unsigned int *codes = is_txa(tx) ?
@@ -239,9 +230,10 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
                                   struct v4l2_subdev_format *sdformat)
 {
        struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
-       struct adv748x_state *state = tx->state;
        struct v4l2_mbus_framefmt *mbusformat;
-       int ret = 0;
+
+       if (sdformat->pad == ADV748X_CSI2_SOURCE)
+               return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
 
        /*
         * Make sure the format is supported, if not default it to
@@ -250,34 +242,14 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
        if (!adv748x_csi2_is_fmt_supported(tx, sdformat->format.code))
                sdformat->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
 
-       mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad,
-                                                sdformat->which);
-       if (!mbusformat)
-               return -EINVAL;
-
-       mutex_lock(&state->mutex);
-
-       if (sdformat->pad == ADV748X_CSI2_SOURCE) {
-               const struct v4l2_mbus_framefmt *sink_fmt;
-
-               sink_fmt = adv748x_csi2_get_pad_format(sd, sd_state,
-                                                      ADV748X_CSI2_SINK,
-                                                      sdformat->which);
-
-               if (!sink_fmt) {
-                       ret = -EINVAL;
-                       goto unlock;
-               }
-
-               sdformat->format = *sink_fmt;
-       }
-
+       mbusformat = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
        *mbusformat = sdformat->format;
 
-unlock:
-       mutex_unlock(&state->mutex);
+       /* Propagate format to the source pad. */
+       mbusformat = v4l2_subdev_state_get_format(sd_state, ADV748X_CSI2_SOURCE);
+       *mbusformat = sdformat->format;
 
-       return ret;
+       return 0;
 }
 
 static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad,
@@ -296,7 +268,7 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad
 
 static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
        .enum_mbus_code = adv748x_csi2_enum_mbus_code,
-       .get_fmt = adv748x_csi2_get_format,
+       .get_fmt = v4l2_subdev_get_fmt,
        .set_fmt = adv748x_csi2_set_format,
        .get_mbus_config = adv748x_csi2_get_mbus_config,
 };
@@ -388,6 +360,11 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
        if (ret)
                goto err_cleanup_subdev;
 
+       tx->sd.state_lock = &state->mutex;
+       ret = v4l2_subdev_init_finalize(&tx->sd);
+       if (ret)
+               goto err_free_ctrl;
+
        ret = v4l2_async_register_subdev(&tx->sd);
        if (ret)
                goto err_free_ctrl;
index d2b5e722e997f38a57196f5035fe102190acd533..9bc0121d0eff39eb4c630f1766e93cdde76bd368 100644 (file)
@@ -75,7 +75,6 @@ enum adv748x_csi2_pads {
 
 struct adv748x_csi2 {
        struct adv748x_state *state;
-       struct v4l2_mbus_framefmt format;
        unsigned int page;
        unsigned int port;
        unsigned int num_lanes;