From: Niklas Söderlund <niklas.soderlund+renesas@xxxxxxxxxxxx> The adv748x CSI-2 transmitter can only transmit one stream over the CSI-2 link, however it can choose which virtual channel is used. This choice effects the CSI-2 receiver and needs to be captured in the frame descriptor information, solve this by implementing .get_frame_desc(). Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@xxxxxxxxxxxx> Reviewed-by: Jacopo Mondi <jacopo+renesas@xxxxxxxxxx> --- drivers/media/i2c/adv748x/adv748x-csi2.c | 31 +++++++++++++++++++++++- drivers/media/i2c/adv748x/adv748x.h | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 1abe34183d7d..d8f7cbee86e7 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -226,9 +226,37 @@ static int adv748x_csi2_set_format(struct v4l2_subdev *sd, return ret; } +static int adv748x_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct v4l2_mbus_framefmt *mbusformat; + + memset(fd, 0, sizeof(*fd)); + + if (pad != ADV748X_CSI2_SOURCE) + return -EINVAL; + + mbusformat = adv748x_csi2_get_pad_format(sd, NULL, ADV748X_CSI2_SINK, + V4L2_SUBDEV_FORMAT_ACTIVE); + if (!mbusformat) + return -EINVAL; + + fd->entry->stream = tx->vc; + fd->entry->bus.csi2.channel = tx->vc; + fd->entry->bus.csi2.data_type = + adv748x_csi2_code_to_datatype(mbusformat->code); + + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + fd->num_entries = 1; + + return 0; +} + static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { .get_fmt = adv748x_csi2_get_format, .set_fmt = adv748x_csi2_set_format, + .get_frame_desc = adv748x_csi2_get_frame_desc, }; /* ----------------------------------------------------------------------------- @@ -295,7 +323,8 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) return 0; /* Initialise the virtual channel */ - adv748x_csi2_set_virtual_channel(tx, 0); + tx->vc = 0; + adv748x_csi2_set_virtual_channel(tx, tx->vc); adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, MEDIA_ENT_F_VID_IF_BRIDGE, diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 5042f9e94aee..4a5a6445604f 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -75,6 +75,7 @@ enum adv748x_csi2_pads { struct adv748x_csi2 { struct adv748x_state *state; + unsigned int vc; struct v4l2_mbus_framefmt format; unsigned int page; unsigned int port; -- 2.21.0