From patchwork Thu Dec 16 17:03:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 525666 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A151C433FE for ; Thu, 16 Dec 2021 17:02:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239901AbhLPRCv (ORCPT ); Thu, 16 Dec 2021 12:02:51 -0500 Received: from relay8-d.mail.gandi.net ([217.70.183.201]:34125 "EHLO relay8-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239897AbhLPRCu (ORCPT ); Thu, 16 Dec 2021 12:02:50 -0500 Received: (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 471531BF203; Thu, 16 Dec 2021 17:02:46 +0000 (UTC) From: Jacopo Mondi To: tomi.valkeinen@ideasonboard.com, sakari.ailus@linux.intel.com, laurent.pinchart@ideasonboard.com, niklas.soderlund@ragnatech.se, kieran.bingham@ideasonboard.com Cc: Jacopo Mondi , Mauro Carvalho Chehab , Hans Verkuil , linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH 2/5] media: adv748x: Add support for v4l2_subdev_state Date: Thu, 16 Dec 2021 18:03:20 +0100 Message-Id: <20211216170323.141321-3-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211216170323.141321-1-jacopo+renesas@jmondi.org> References: <20211216170323.141321-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Create and initialize the v4l2_subdev_state for the adv748x CSI-2 subdevice in order to prepare to support routing of the video stream. Create the subdevice state with v4l2_subdev_init_finalize() and implement the init_cfg() operation to guarantee the state is initialized correctly with the default routing set. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 57 +++++++++++++++++++++++- drivers/media/i2c/adv748x/adv748x.h | 3 ++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 6cbb47a715ab..9061c34ba561 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -139,6 +139,50 @@ static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = { * But we must support setting the pad formats for format propagation. */ +static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + /* One route for each virtual channel. Route 0 enabled by default. */ + struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = { + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 1, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 2, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 3, + }, + }; + struct v4l2_subdev_krouting routing; + int ret; + + routing.num_routes = ADV748X_CSI2_STREAMS; + routing.routes = routes; + + v4l2_subdev_lock_state(state); + ret = v4l2_subdev_set_routing(sd, state, &routing); + v4l2_subdev_unlock_state(state); + + return ret; +} + static struct v4l2_mbus_framefmt * adv748x_csi2_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, @@ -244,6 +288,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 = { + .init_cfg = adv748x_csi2_init_cfg, .get_fmt = adv748x_csi2_get_format, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, @@ -313,7 +358,8 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) return 0; adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, - MEDIA_ENT_F_VID_IF_BRIDGE, 0, + MEDIA_ENT_F_VID_IF_BRIDGE, + V4L2_SUBDEV_FL_MULTIPLEXED, is_txa(tx) ? "txa" : "txb"); /* Ensure that matching is based upon the endpoint fwnodes */ @@ -330,10 +376,14 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) if (ret) return ret; - ret = adv748x_csi2_init_controls(tx); + ret = v4l2_subdev_init_finalize(&tx->sd); if (ret) goto err_free_media; + ret = adv748x_csi2_init_controls(tx); + if (ret) + goto err_free_state; + ret = v4l2_async_register_subdev(&tx->sd); if (ret) goto err_free_ctrl; @@ -342,6 +392,8 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) err_free_ctrl: v4l2_ctrl_handler_free(&tx->ctrl_hdl); +err_free_state: + v4l2_subdev_cleanup(&tx->sd); err_free_media: media_entity_cleanup(&tx->sd.entity); @@ -354,6 +406,7 @@ void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) return; v4l2_async_unregister_subdev(&tx->sd); + v4l2_subdev_cleanup(&tx->sd); media_entity_cleanup(&tx->sd.entity); v4l2_ctrl_handler_free(&tx->ctrl_hdl); } diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 92c8caee6a42..d651c8390e6f 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -73,6 +73,9 @@ enum adv748x_csi2_pads { /* CSI2 transmitters can have 2 internal connections, HDMI/AFE */ #define ADV748X_CSI2_MAX_SUBDEVS 2 +/* CSI2 number of streams: 1 for each CSI-2 Virtual channel output. */ +#define ADV748X_CSI2_STREAMS 4 + struct adv748x_csi2 { struct adv748x_state *state; struct v4l2_mbus_framefmt format; From patchwork Thu Dec 16 17:03:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 525665 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2D5FC433FE for ; Thu, 16 Dec 2021 17:02:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239905AbhLPRC6 (ORCPT ); Thu, 16 Dec 2021 12:02:58 -0500 Received: from relay8-d.mail.gandi.net ([217.70.183.201]:46035 "EHLO relay8-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239859AbhLPRC6 (ORCPT ); Thu, 16 Dec 2021 12:02:58 -0500 Received: (Authenticated sender: jacopo@jmondi.org) by relay8-d.mail.gandi.net (Postfix) with ESMTPSA id AC0521BF20B; Thu, 16 Dec 2021 17:02:52 +0000 (UTC) From: Jacopo Mondi To: tomi.valkeinen@ideasonboard.com, sakari.ailus@linux.intel.com, laurent.pinchart@ideasonboard.com, niklas.soderlund@ragnatech.se, kieran.bingham@ideasonboard.com Cc: Jacopo Mondi , Mauro Carvalho Chehab , Hans Verkuil , linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH 4/5] media: adv748x: Implement .get_frame_desc() Date: Thu, 16 Dec 2021 18:03:22 +0100 Message-Id: <20211216170323.141321-5-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211216170323.141321-1-jacopo+renesas@jmondi.org> References: <20211216170323.141321-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement the get_frame_desc subdev pad operation. Implement the get_frame_desc pad operation to allow retrieving the stream configuration of the adv748x csi2 subdevice. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 93 ++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 549c3cd96006..9824ebe44eb1 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -14,6 +14,50 @@ #include "adv748x.h" +/* Describes a format bit depth and CSI-2 defined Data Type. */ +struct adv748x_csi2_format_info { + u8 dt; + u8 bpp; +}; + +static int adv748x_csi2_get_format_info(struct adv748x_csi2 *tx, + u32 mbus_code, + struct adv748x_csi2_format_info *fmt) +{ + switch (mbus_code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_2X8: + fmt->dt = 0x1e; + fmt->bpp = 16; + break; + case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV10_1X20: + fmt->dt = 0x1f; + fmt->bpp = 20; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + fmt->dt = 0x22; + fmt->bpp = 16; + break; + case MEDIA_BUS_FMT_RGB666_1X18: + fmt->dt = 0x23; + fmt->bpp = 18; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + fmt->dt = 0x24; + fmt->bpp = 24; + break; + default: + dev_err(tx->state->dev, + "Unsupported media bus code: %u\n", mbus_code); + return -EINVAL; + } + + return 0; +} + int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc) { return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT); @@ -248,11 +292,60 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad return 0; } +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 adv748x_csi2_format_info info = {}; + struct v4l2_mbus_frame_desc_entry *entry; + struct v4l2_subdev_route *route; + struct v4l2_subdev_state *state; + struct v4l2_mbus_framefmt *fmt; + int ret; + + if (pad != ADV748X_CSI2_SOURCE) + return -EINVAL; + + state = v4l2_subdev_lock_active_state(sd); + + /* A single route is available. */ + route = &state->routing.routes[0]; + fmt = v4l2_state_get_stream_format(state, pad, route->source_stream); + if (!fmt) { + ret = -EINVAL; + goto out; + } + + ret = adv748x_csi2_get_format_info(tx, fmt->code, &info); + if (ret) + goto out; + + memset(fd, 0, sizeof(*fd)); + + /* A single stream is available. */ + fd->num_entries = 1; + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + + entry = &fd->entry[0]; + entry->stream = 0; + entry->flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX; + entry->length = fmt->width * fmt->height * info.bpp / 8; + entry->pixelcode = fmt->code; + entry->bus.csi2.vc = route->source_stream; + entry->bus.csi2.dt = info.dt; + +out: + v4l2_subdev_unlock_state(state); + + return ret; +} + static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { .init_cfg = adv748x_csi2_init_cfg, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, + .get_frame_desc = adv748x_csi2_get_frame_desc, }; /* -----------------------------------------------------------------------------