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: 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>
This commit is contained in:
parent
61893eccf6
commit
3164347e24
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user