Commit 3164347e authored by Jacopo Mondi's avatar Jacopo Mondi Committed by Laurent Pinchart

media: adv748x-csi2: Use the subdev active state

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: default avatarJacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Tested-by: default avatarNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Link: https://lore.kernel.org/r/20240617161135.130719-9-jacopo.mondi@ideasonboard.comSigned-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent 61893ecc
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
...@@ -68,7 +67,33 @@ static int adv748x_csi2_register_link(struct adv748x_csi2 *tx, ...@@ -68,7 +67,33 @@ static int adv748x_csi2_register_link(struct adv748x_csi2 *tx,
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* v4l2_subdev_internal_ops * 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 * We use the internal registered operation to be able to ensure that our
* incremental subdevices (not connected in the forward path) can be registered * incremental subdevices (not connected in the forward path) can be registered
* against the resulting video path and media device. * against the resulting video path and media device.
...@@ -118,6 +143,7 @@ static int adv748x_csi2_registered(struct v4l2_subdev *sd) ...@@ -118,6 +143,7 @@ static int adv748x_csi2_registered(struct v4l2_subdev *sd)
} }
static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = { static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
.init_state = adv748x_csi2_init_state,
.registered = adv748x_csi2_registered, .registered = adv748x_csi2_registered,
}; };
...@@ -183,41 +209,6 @@ static int adv748x_csi2_enum_mbus_code(struct v4l2_subdev *sd, ...@@ -183,41 +209,6 @@ static int adv748x_csi2_enum_mbus_code(struct v4l2_subdev *sd,
return 0; 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) static bool adv748x_csi2_is_fmt_supported(struct adv748x_csi2 *tx, u32 code)
{ {
const unsigned int *codes = is_txa(tx) ? const unsigned int *codes = is_txa(tx) ?
...@@ -239,9 +230,10 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd, ...@@ -239,9 +230,10 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
struct v4l2_subdev_format *sdformat) struct v4l2_subdev_format *sdformat)
{ {
struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
struct adv748x_state *state = tx->state;
struct v4l2_mbus_framefmt *mbusformat; 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 * 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, ...@@ -250,34 +242,14 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd,
if (!adv748x_csi2_is_fmt_supported(tx, sdformat->format.code)) if (!adv748x_csi2_is_fmt_supported(tx, sdformat->format.code))
sdformat->format.code = MEDIA_BUS_FMT_UYVY8_1X16; sdformat->format.code = MEDIA_BUS_FMT_UYVY8_1X16;
mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad, mbusformat = v4l2_subdev_state_get_format(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 = sdformat->format; *mbusformat = sdformat->format;
unlock: /* Propagate format to the source pad. */
mutex_unlock(&state->mutex); 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, 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 ...@@ -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 = { static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = {
.enum_mbus_code = adv748x_csi2_enum_mbus_code, .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, .set_fmt = adv748x_csi2_set_format,
.get_mbus_config = adv748x_csi2_get_mbus_config, .get_mbus_config = adv748x_csi2_get_mbus_config,
}; };
...@@ -388,6 +360,11 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) ...@@ -388,6 +360,11 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
if (ret) if (ret)
goto err_cleanup_subdev; 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); ret = v4l2_async_register_subdev(&tx->sd);
if (ret) if (ret)
goto err_free_ctrl; goto err_free_ctrl;
......
...@@ -75,7 +75,6 @@ enum adv748x_csi2_pads { ...@@ -75,7 +75,6 @@ enum adv748x_csi2_pads {
struct adv748x_csi2 { struct adv748x_csi2 {
struct adv748x_state *state; struct adv748x_state *state;
struct v4l2_mbus_framefmt format;
unsigned int page; unsigned int page;
unsigned int port; unsigned int port;
unsigned int num_lanes; unsigned int num_lanes;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment