This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: vimc: sensor: Use subdev active state
Author:  Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Date:    Thu Apr 25 02:57:39 2024 +0300

Store the active formats and crop rectangle in the subdevice active
state. This simplifies implementation of the format and selection
accessors, and allows using the v4l2_subdev_get_fmt() helper to
implement the .get_fmt() operation.

The active configuration that is used in the .process_frame() handler is
still stored in the vimc_sensor_device structure. The driver could
instead access the active state in the .process_frame() handler, but the
required locking could interfere with the real time constraints of the
frame processing. This data would be stored in registers in the
.s_stream() handler for real hardware, storing it in dedicated storage
thus mimics a real driver. To differentiate them from the rest of the
device private data, move the corresponding fields to a sub-structure of
vimc_sensor_device named hw.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Signed-off-by: Shuah Khan <sk...@linuxfoundation.org>
Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 drivers/media/test-drivers/vimc/vimc-sensor.c | 108 ++++++++++++--------------
 1 file changed, 50 insertions(+), 58 deletions(-)

---

diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c 
b/drivers/media/test-drivers/vimc/vimc-sensor.c
index 9eb24c4791bf..027767777763 100644
--- a/drivers/media/test-drivers/vimc/vimc-sensor.c
+++ b/drivers/media/test-drivers/vimc/vimc-sensor.c
@@ -24,13 +24,20 @@ struct vimc_sensor_device {
        struct vimc_ent_device ved;
        struct v4l2_subdev sd;
        struct tpg_data tpg;
-       u8 *frame;
-       enum vimc_sensor_osd_mode osd_value;
-       u64 start_stream_ts;
-       /* The active format */
-       struct v4l2_mbus_framefmt mbus_format;
        struct v4l2_ctrl_handler hdl;
        struct media_pad pad;
+
+       u8 *frame;
+
+       /*
+        * Virtual "hardware" configuration, filled when the stream starts or
+        * when controls are set.
+        */
+       struct {
+               struct v4l2_area size;
+               enum vimc_sensor_osd_mode osd_value;
+               u64 start_stream_ts;
+       } hw;
 };
 
 static const struct v4l2_mbus_framefmt fmt_default = {
@@ -88,36 +95,22 @@ static int vimc_sensor_enum_frame_size(struct v4l2_subdev 
*sd,
        return 0;
 }
 
-static int vimc_sensor_get_fmt(struct v4l2_subdev *sd,
-                              struct v4l2_subdev_state *sd_state,
-                              struct v4l2_subdev_format *fmt)
+static void vimc_sensor_tpg_s_format(struct vimc_sensor_device *vsensor,
+                                    const struct v4l2_mbus_framefmt *format)
 {
-       struct vimc_sensor_device *vsensor =
-                               container_of(sd, struct vimc_sensor_device, sd);
-
-       fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
-                     *v4l2_subdev_state_get_format(sd_state, fmt->pad) :
-                     vsensor->mbus_format;
+       const struct vimc_pix_map *vpix = vimc_pix_map_by_code(format->code);
 
-       return 0;
-}
-
-static void vimc_sensor_tpg_s_format(struct vimc_sensor_device *vsensor)
-{
-       const struct vimc_pix_map *vpix =
-                               vimc_pix_map_by_code(vsensor->mbus_format.code);
-
-       tpg_reset_source(&vsensor->tpg, vsensor->mbus_format.width,
-                        vsensor->mbus_format.height, 
vsensor->mbus_format.field);
-       tpg_s_bytesperline(&vsensor->tpg, 0, vsensor->mbus_format.width * 
vpix->bpp);
-       tpg_s_buf_height(&vsensor->tpg, vsensor->mbus_format.height);
+       tpg_reset_source(&vsensor->tpg, format->width, format->height,
+                        format->field);
+       tpg_s_bytesperline(&vsensor->tpg, 0, format->width * vpix->bpp);
+       tpg_s_buf_height(&vsensor->tpg, format->height);
        tpg_s_fourcc(&vsensor->tpg, vpix->pixelformat);
        /* TODO: add support for V4L2_FIELD_ALTERNATE */
-       tpg_s_field(&vsensor->tpg, vsensor->mbus_format.field, false);
-       tpg_s_colorspace(&vsensor->tpg, vsensor->mbus_format.colorspace);
-       tpg_s_ycbcr_enc(&vsensor->tpg, vsensor->mbus_format.ycbcr_enc);
-       tpg_s_quantization(&vsensor->tpg, vsensor->mbus_format.quantization);
-       tpg_s_xfer_func(&vsensor->tpg, vsensor->mbus_format.xfer_func);
+       tpg_s_field(&vsensor->tpg, format->field, false);
+       tpg_s_colorspace(&vsensor->tpg, format->colorspace);
+       tpg_s_ycbcr_enc(&vsensor->tpg, format->ycbcr_enc);
+       tpg_s_quantization(&vsensor->tpg, format->quantization);
+       tpg_s_xfer_func(&vsensor->tpg, format->xfer_func);
 }
 
 static void vimc_sensor_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
@@ -148,15 +141,11 @@ static int vimc_sensor_set_fmt(struct v4l2_subdev *sd,
        struct vimc_sensor_device *vsensor = v4l2_get_subdevdata(sd);
        struct v4l2_mbus_framefmt *mf;
 
-       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-               /* Do not change the format while stream is on */
-               if (vsensor->frame)
-                       return -EBUSY;
+       /* Do not change the format while stream is on */
+       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && vsensor->frame)
+               return -EBUSY;
 
-               mf = &vsensor->mbus_format;
-       } else {
-               mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
-       }
+       mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
 
        /* Set the new format */
        vimc_sensor_adjust_fmt(&fmt->format);
@@ -181,7 +170,7 @@ static int vimc_sensor_set_fmt(struct v4l2_subdev *sd,
 static const struct v4l2_subdev_pad_ops vimc_sensor_pad_ops = {
        .enum_mbus_code         = vimc_sensor_enum_mbus_code,
        .enum_frame_size        = vimc_sensor_enum_frame_size,
-       .get_fmt                = vimc_sensor_get_fmt,
+       .get_fmt                = v4l2_subdev_get_fmt,
        .set_fmt                = vimc_sensor_set_fmt,
 };
 
@@ -198,7 +187,7 @@ static void *vimc_sensor_process_frame(struct 
vimc_ent_device *ved,
 
        tpg_fill_plane_buffer(&vsensor->tpg, 0, 0, vsensor->frame);
        tpg_calc_text_basep(&vsensor->tpg, basep, 0, vsensor->frame);
-       switch (vsensor->osd_value) {
+       switch (vsensor->hw.osd_value) {
        case VIMC_SENSOR_OSD_SHOW_ALL: {
                const char *order = tpg_g_color_order(&vsensor->tpg);
 
@@ -212,15 +201,14 @@ static void *vimc_sensor_process_frame(struct 
vimc_ent_device *ved,
                         vsensor->tpg.hue);
                tpg_gen_text(&vsensor->tpg, basep, line++ * line_height, 16, 
str);
                snprintf(str, sizeof(str), "sensor size: %dx%d",
-                        vsensor->mbus_format.width,
-                        vsensor->mbus_format.height);
+                        vsensor->hw.size.width, vsensor->hw.size.height);
                tpg_gen_text(&vsensor->tpg, basep, line++ * line_height, 16, 
str);
                fallthrough;
        }
        case VIMC_SENSOR_OSD_SHOW_COUNTERS: {
                unsigned int ms;
 
-               ms = div_u64(ktime_get_ns() - vsensor->start_stream_ts, 
1000000);
+               ms = div_u64(ktime_get_ns() - vsensor->hw.start_stream_ts, 
1000000);
                snprintf(str, sizeof(str), "%02d:%02d:%02d:%03d",
                         (ms / (60 * 60 * 1000)) % 24,
                         (ms / (60 * 1000)) % 60,
@@ -243,15 +231,25 @@ static int vimc_sensor_s_stream(struct v4l2_subdev *sd, 
int enable)
                                container_of(sd, struct vimc_sensor_device, sd);
 
        if (enable) {
+               const struct v4l2_mbus_framefmt *format;
+               struct v4l2_subdev_state *state;
                const struct vimc_pix_map *vpix;
                unsigned int frame_size;
 
-               vsensor->start_stream_ts = ktime_get_ns();
+               state = v4l2_subdev_lock_and_get_active_state(sd);
+               format = v4l2_subdev_state_get_format(state, 0);
 
-               /* Calculate the frame size */
-               vpix = vimc_pix_map_by_code(vsensor->mbus_format.code);
-               frame_size = vsensor->mbus_format.width * vpix->bpp *
-                            vsensor->mbus_format.height;
+               /* Configure the test pattern generator. */
+               vimc_sensor_tpg_s_format(vsensor, format);
+
+               /* Calculate the frame size. */
+               vpix = vimc_pix_map_by_code(format->code);
+               frame_size = format->width * vpix->bpp * format->height;
+
+               vsensor->hw.size.width = format->width;
+               vsensor->hw.size.height = format->height;
+
+               v4l2_subdev_unlock_state(state);
 
                /*
                 * Allocate the frame buffer. Use vmalloc to be able to
@@ -261,9 +259,7 @@ static int vimc_sensor_s_stream(struct v4l2_subdev *sd, int 
enable)
                if (!vsensor->frame)
                        return -ENOMEM;
 
-               /* configure the test pattern generator */
-               vimc_sensor_tpg_s_format(vsensor);
-
+               vsensor->hw.start_stream_ts = ktime_get_ns();
        } else {
 
                vfree(vsensor->frame);
@@ -321,7 +317,7 @@ static int vimc_sensor_s_ctrl(struct v4l2_ctrl *ctrl)
                tpg_s_saturation(&vsensor->tpg, ctrl->val);
                break;
        case VIMC_CID_OSD_TEXT_MODE:
-               vsensor->osd_value = ctrl->val;
+               vsensor->hw.osd_value = ctrl->val;
                break;
        default:
                return -EINVAL;
@@ -414,8 +410,7 @@ static struct vimc_ent_device *vimc_sensor_add(struct 
vimc_device *vimc,
        }
 
        /* Initialize the test pattern generator */
-       tpg_init(&vsensor->tpg, vsensor->mbus_format.width,
-                vsensor->mbus_format.height);
+       tpg_init(&vsensor->tpg, fmt_default.width, fmt_default.height);
        ret = tpg_alloc(&vsensor->tpg, VIMC_FRAME_MAX_WIDTH);
        if (ret)
                goto err_free_hdl;
@@ -432,9 +427,6 @@ static struct vimc_ent_device *vimc_sensor_add(struct 
vimc_device *vimc,
        vsensor->ved.process_frame = vimc_sensor_process_frame;
        vsensor->ved.dev = vimc->mdev.dev;
 
-       /* Initialize the frame format */
-       vsensor->mbus_format = fmt_default;
-
        return &vsensor->ved;
 
 err_free_tpg:

Reply via email to