From patchwork Sun Jul 19 11:27:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arash Golgol X-Patchwork-Id: 2690 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id E00AC1C0BBF for ; Sun, 19 Jul 2026 09:57:45 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-24518-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-24518-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 5CD8C3013A93 for ; Sun, 19 Jul 2026 07:57:35 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 04FAB3570AD; Sun, 19 Jul 2026 07:57:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="IItPiQMO" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-lj1-f170.google.com (mail-lj1-f170.google.com [209.85.208.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 670D82E762C for ; Sun, 19 Jul 2026 07:57:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784447854; cv=none; b=fDCaKQXwndgra6Vh1Le+P/SSUGtsHPqrWteQ0BuIxOwl7XsBkiG8H+Aj4ETomurMXkeNtveWU3fDOp9+cXpUrWHgwLsrAHwP2qRofCsfmyziRjUlTz0829PhuA12gM2/i7pEQ3TWvbVzQSI6m8ifWC4ea76el/rryrnurKd7JOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784447854; c=relaxed/simple; bh=MHFzYqIGRj106kkMhEdJylVQ1UEZIPIkqE1sIJBWJzk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OhKX2/QK1Qobog1SJgG5Q3A0Zt/DJD7O1ulxu2yyTLE8Y8x+0WoeHVkYnEVVW9V+bwhqAUu4x6uLpiZmDx3Fs+JG9oXZgUVKbckVQIpIcGGDBfVppVqYdK8IsgId+eutwCqpmwGjkPjNNmTr+Gi93JtPDPc8zwEsy6kVjaq6hYU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=IItPiQMO; arc=none smtp.client-ip=209.85.208.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lj1-f170.google.com with SMTP id 38308e7fff4ca-39c8dbf4ef0so82899251fa.2 for ; Sun, 19 Jul 2026 00:57:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784447850; x=1785052650; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=y5SXetdcGvVGrOjT9+Mkpgt9r2nohvIBG0bwxn1sZBs=; b=IItPiQMOiDDYtvSATceJn2hHhF6fgul0bc0qgdJSNmnJoeQa/wyvOoxEvBArAxy2+o /7PtWfKT912QJQ18YKSM68x+Tu/Ts/6YK0AoXxfhKIE9fcWv/5vzDCGfsNq1JL7z8L3S uuQulffv1+D32JxOAIC8Lz0F6sMdinM4qoQBj+z48kIGsOZg68mPFunXe10DafYLCdvh q1tFJ3kHbUIiGXZ7aaNwa24SAS7kgXwCbLt5aDH9SW060jSERO7QE9Nj95Acb+fQXKPQ ifg/FfrudO1eqg9rCA8ug5z5Uo8Ngs03ayThfSrXe6QswLRHSntPcuCkbxZFcJ+Fdudx fnew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784447850; x=1785052650; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=y5SXetdcGvVGrOjT9+Mkpgt9r2nohvIBG0bwxn1sZBs=; b=baej5DmdFJTGTdDVenh7Z775aNjkLfyXV07ukM66nt4cnfQYTnDbFvekXYpsCBF2Wo 7XoJX5+OQ9GCsWn5rdmSDzc2oHwKY63s+df/ZohQn6aChAItCsnhcyA6dQyZK7BG9XQX I/nC3tVkvWDAMEAKopsMHqeVcOSYbS3DBGOSucfDYlkUXGFNTcNlXKEWVP0DHYiwlD+T C1lIyG2VR0HdfPbwu/yr0moYC9XZh/trmTCqvCjhsOA7FZt5ORumm/MGCIF+fZyY+VoL 67FPuv0Cwyn98DK9m8jIJrwzF0Al/OTY9mi/jdJbzcDyjWoPUtNBSeJoOXgoT+rpKue+ Yh4Q== X-Forwarded-Encrypted: i=1; AHgh+RoVrqI1nV/L0B/xTbxJ/qnOrhZe2nAHk9Brgz2mO5/BfJTTA5PE2LeIoGk56VXN49NQaHKiG/IZVRfiIQ==@lists.linux.dev X-Gm-Message-State: AOJu0YxqumIjLrZx8YnjLP3WbWW2W9M2DjwbodSizLOGoAKD+xkv2Ygm IrHFU5k6S8ui1XfJR6q9nvQ6aIeU4eAl9FU05x6unffLJiEig5TnGznC X-Gm-Gg: AfdE7cmXgxSULh7erFf2guto/vlPjw+mJhP7057BB6QxcC7n6xAm6ETT+OBfY+OYwcV Qh/4nQT/4jDwWr59A6anAbjFhnc8ypVtmRmyFKeFTYqxS2LNsDHV8nLfFngnDxUqvsgQeW/fs1x CySoyUYN06pvXKZDvMCuFXJBaakuDbVqkc1NBewya6FSnq7AqYFMOrLNoH+eofUnv51j0XE0TRy QEdkVmnRndac9gZhXMo6adTD1A1gVDMPyyiuAybbHKzbcuctem5wnIAzzR8qKHkaKQN3275TX1R ijpYC8HLCZ2KslssFq6cy2W/Ueqoct86bvXHhQAehGS8TzFiun50V24AiQYolsQXRDLZ2YOsha/ xZz+G9ANXrZRxK+Yt959RBOJAdfPDbfoMFmDWW7wuE5T2kmKWM3h7R5FweHS62qLXOBUYecMOJ2 twdY8ajQNLwaGLvy3GqfSGGd1rOllS/lNXhJfv66ltvR10fpiQlsbQeYa1Xrw= X-Received: by 2002:a2e:a884:0:b0:39b:3e32:4a58 with SMTP id 38308e7fff4ca-39eb2776c2fmr20397071fa.10.1784447850096; Sun, 19 Jul 2026 00:57:30 -0700 (PDT) Received: from thinkpad ([5.212.61.200]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-39eb4e5b31esm10490951fa.12.2026.07.19.00.57.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 00:57:29 -0700 (PDT) From: Arash Golgol To: linux-media@vger.kernel.org Cc: yong.deng@magewell.com, paulk@sys-base.io, mchehab@kernel.org, wens@kernel.org, jernej.skrabec@gmail.com, samuel@sholland.org, laurent.pinchart@ideasonboard.com, linux-sunxi@lists.linux.dev, Arash Golgol Subject: [PATCH v5 1/2] media: sun6i-csi: bridge: Use V4L2 subdev active state Date: Sun, 19 Jul 2026 14:57:13 +0330 Message-Id: <20260719112714.72802-2-arash.golgol@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260719112714.72802-1-arash.golgol@gmail.com> References: <20260719112714.72802-1-arash.golgol@gmail.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-0.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.234.253.10:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; DATE_IN_FUTURE(0.50)[3]; R_MISSING_CHARSET(0.50)[]; MAILLIST(-0.15)[generic]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; TAGGED_RCPT(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sea.lore.kernel.org:rdns,sea.lore.kernel.org:helo,ideasonboard.com:email,sys-base.io:email]; FREEMAIL_CC(0.00)[magewell.com,sys-base.io,kernel.org,gmail.com,sholland.org,ideasonboard.com,lists.linux.dev]; FUZZY_BLOCKED(0.00)[rspamd.com]; FORGED_SENDER_MAILLIST(0.00)[]; FROM_HAS_DN(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.0/19, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; RCPT_COUNT_SEVEN(0.00)[10]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[arashgolgol@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; MIME_TRACE(0.00)[0:+]; TAGGED_FROM(0.00)[bounces-24518-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: E00AC1C0BBF X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= Use the V4L2 subdev active state API to store the active format. This simplifies the driver not only by dropping the bridge mbus_format field, but it also allows dropping the bridge lock, replaced with the state lock. Previously, capture accessed bridge private state directly. After moving to framework-managed state, resolve the format through the subdev pad API. The sun6i-csi-bridge hardware does not perform any format conversion. Enforce identical formats on the sink and source pads in the set_fmt() and init_state() callbacks. Signed-off-by: Arash Golgol Reviewed-by: Paul Kocialkowski Tested-by: Paul Kocialkowski Reviewed-by: Laurent Pinchart --- .../sunxi/sun6i-csi/sun6i_csi_bridge.c | 155 ++++++++---------- .../sunxi/sun6i-csi/sun6i_csi_bridge.h | 9 - .../sunxi/sun6i-csi/sun6i_csi_capture.c | 27 ++- 3 files changed, 86 insertions(+), 105 deletions(-) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c index d006d9dd0170..43a85bcc2ba2 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c @@ -13,26 +13,6 @@ #include "sun6i_csi_bridge.h" #include "sun6i_csi_reg.h" -/* Helpers */ - -void sun6i_csi_bridge_dimensions(struct sun6i_csi_device *csi_dev, - unsigned int *width, unsigned int *height) -{ - if (width) - *width = csi_dev->bridge.mbus_format.width; - if (height) - *height = csi_dev->bridge.mbus_format.height; -} - -void sun6i_csi_bridge_format(struct sun6i_csi_device *csi_dev, - u32 *mbus_code, u32 *field) -{ - if (mbus_code) - *mbus_code = csi_dev->bridge.mbus_format.code; - if (field) - *field = csi_dev->bridge.mbus_format.field; -} - /* Format */ static const struct sun6i_csi_bridge_format sun6i_csi_bridge_formats[] = { @@ -226,7 +206,8 @@ static void sun6i_csi_bridge_disable(struct sun6i_csi_device *csi_dev) } static void -sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev) +sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev, + const struct v4l2_mbus_framefmt *mbus_format) { struct device *dev = csi_dev->dev; struct regmap *regmap = csi_dev->regmap; @@ -234,11 +215,9 @@ sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev) &csi_dev->bridge.source_parallel.endpoint; unsigned char bus_width = endpoint->bus.parallel.bus_width; unsigned int flags = endpoint->bus.parallel.flags; - u32 field; + u32 field = mbus_format->field; u32 value = SUN6I_CSI_IF_CFG_IF_CSI; - sun6i_csi_bridge_format(csi_dev, NULL, &field); - if (field == V4L2_FIELD_INTERLACED || field == V4L2_FIELD_INTERLACED_TB || field == V4L2_FIELD_INTERLACED_BT) @@ -317,13 +296,12 @@ sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev) } static void -sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev) +sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev, + const struct v4l2_mbus_framefmt *mbus_format) { struct regmap *regmap = csi_dev->regmap; u32 value = SUN6I_CSI_IF_CFG_IF_MIPI; - u32 field; - - sun6i_csi_bridge_format(csi_dev, NULL, &field); + u32 field = mbus_format->field; if (field == V4L2_FIELD_INTERLACED || field == V4L2_FIELD_INTERLACED_TB || @@ -335,19 +313,20 @@ sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev) regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value); } -static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev) +static void +sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev, + const struct v4l2_mbus_framefmt *mbus_format) { struct regmap *regmap = csi_dev->regmap; bool capture_streaming = csi_dev->capture.state.streaming; const struct sun6i_csi_bridge_format *bridge_format; const struct sun6i_csi_capture_format *capture_format; - u32 mbus_code, field, pixelformat; + u32 pixelformat; + u32 field = mbus_format->field; u8 input_format, input_yuv_seq, output_format; u32 value = 0; - sun6i_csi_bridge_format(csi_dev, &mbus_code, &field); - - bridge_format = sun6i_csi_bridge_format_find(mbus_code); + bridge_format = sun6i_csi_bridge_format_find(mbus_format->code); if (WARN_ON(!bridge_format)) return; @@ -391,16 +370,17 @@ static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev) } static void sun6i_csi_bridge_configure(struct sun6i_csi_device *csi_dev, - struct sun6i_csi_bridge_source *source) + struct sun6i_csi_bridge_source *source, + const struct v4l2_mbus_framefmt *mbus_format) { struct sun6i_csi_bridge *bridge = &csi_dev->bridge; if (source == &bridge->source_parallel) - sun6i_csi_bridge_configure_parallel(csi_dev); + sun6i_csi_bridge_configure_parallel(csi_dev, mbus_format); else - sun6i_csi_bridge_configure_mipi_csi2(csi_dev); + sun6i_csi_bridge_configure_mipi_csi2(csi_dev, mbus_format); - sun6i_csi_bridge_configure_format(csi_dev); + sun6i_csi_bridge_configure_format(csi_dev, mbus_format); } /* V4L2 Subdev */ @@ -415,6 +395,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) struct sun6i_csi_bridge_source *source; struct v4l2_subdev *source_subdev; struct media_pad *remote_pad; + struct v4l2_subdev_state *state; + const struct v4l2_mbus_framefmt *mbus_format; int ret; /* Source */ @@ -433,6 +415,10 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) else source = &bridge->source_mipi_csi2; + /* Active State */ + + state = v4l2_subdev_lock_and_get_active_state(subdev); + if (!on) { v4l2_subdev_call(source_subdev, video, s_stream, 0); ret = 0; @@ -443,7 +429,7 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) ret = pm_runtime_resume_and_get(dev); if (ret < 0) - return ret; + goto unlock; /* Clear */ @@ -451,7 +437,9 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) /* Configure */ - sun6i_csi_bridge_configure(csi_dev, source); + mbus_format = v4l2_subdev_state_get_format(state, + SUN6I_CSI_BRIDGE_PAD_SINK); + sun6i_csi_bridge_configure(csi_dev, source, mbus_format); if (capture_streaming) sun6i_csi_capture_configure(csi_dev); @@ -472,7 +460,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) if (ret && ret != -ENOIOCTLCMD) goto disable; - return 0; + ret = 0; + goto unlock; disable: if (capture_streaming) @@ -482,6 +471,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on) pm_runtime_put(dev); +unlock: + v4l2_subdev_unlock_state(state); return ret; } @@ -504,21 +495,23 @@ sun6i_csi_bridge_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format) static int sun6i_csi_bridge_init_state(struct v4l2_subdev *subdev, struct v4l2_subdev_state *state) { - struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev); - unsigned int pad = SUN6I_CSI_BRIDGE_PAD_SINK; - struct v4l2_mbus_framefmt *mbus_format = - v4l2_subdev_state_get_format(state, pad); - struct mutex *lock = &csi_dev->bridge.lock; + unsigned int pad; - mutex_lock(lock); + /* + * This subdev does not perform format conversion, + * initialize both pads identically. + */ + for (pad = 0; pad < subdev->entity.num_pads; pad++) { + struct v4l2_mbus_framefmt *mbus_format; - mbus_format->code = sun6i_csi_bridge_formats[0].mbus_code; - mbus_format->width = 1280; - mbus_format->height = 720; + mbus_format = v4l2_subdev_state_get_format(state, pad); - sun6i_csi_bridge_mbus_format_prepare(mbus_format); + mbus_format->code = sun6i_csi_bridge_formats[0].mbus_code; + mbus_format->width = 1280; + mbus_format->height = 720; - mutex_unlock(lock); + sun6i_csi_bridge_mbus_format_prepare(mbus_format); + } return 0; } @@ -536,53 +529,32 @@ sun6i_csi_bridge_enum_mbus_code(struct v4l2_subdev *subdev, return 0; } -static int sun6i_csi_bridge_get_fmt(struct v4l2_subdev *subdev, - struct v4l2_subdev_state *state, - struct v4l2_subdev_format *format) -{ - struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev); - struct v4l2_mbus_framefmt *mbus_format = &format->format; - struct mutex *lock = &csi_dev->bridge.lock; - - mutex_lock(lock); - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *mbus_format = *v4l2_subdev_state_get_format(state, - format->pad); - else - *mbus_format = csi_dev->bridge.mbus_format; - - mutex_unlock(lock); - - return 0; -} - static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev, struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev); - struct v4l2_mbus_framefmt *mbus_format = &format->format; - struct mutex *lock = &csi_dev->bridge.lock; + struct v4l2_mbus_framefmt *fmt; - mutex_lock(lock); + /* The format on the source pad always matches the sink pad. */ + if (format->pad != SUN6I_CSI_BRIDGE_PAD_SINK) + return v4l2_subdev_get_fmt(subdev, state, format); - sun6i_csi_bridge_mbus_format_prepare(mbus_format); + sun6i_csi_bridge_mbus_format_prepare(&format->format); - if (format->which == V4L2_SUBDEV_FORMAT_TRY) - *v4l2_subdev_state_get_format(state, format->pad) = - *mbus_format; - else - csi_dev->bridge.mbus_format = *mbus_format; + /* Set the format on the sink pad. */ + fmt = v4l2_subdev_state_get_format(state, format->pad); + *fmt = format->format; - mutex_unlock(lock); + /* Propagate the format to the source pad. */ + fmt = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE); + *fmt = format->format; return 0; } static const struct v4l2_subdev_pad_ops sun6i_csi_bridge_pad_ops = { .enum_mbus_code = sun6i_csi_bridge_enum_mbus_code, - .get_fmt = sun6i_csi_bridge_get_fmt, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = sun6i_csi_bridge_set_fmt, }; @@ -780,8 +752,6 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) }; int ret; - mutex_init(&bridge->lock); - /* V4L2 Subdev */ v4l2_subdev_init(subdev, &sun6i_csi_bridge_subdev_ops); @@ -809,6 +779,12 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) if (ret < 0) return ret; + /* V4L2 Subdev finalize */ + + ret = v4l2_subdev_init_finalize(subdev); + if (ret < 0) + goto error_media_entity; + /* V4L2 Subdev */ if (csi_dev->isp_available) @@ -818,7 +794,7 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) if (ret) { dev_err(dev, "failed to register v4l2 subdev: %d\n", ret); - goto error_media_entity; + goto error_subdev_finalize; } /* V4L2 Async */ @@ -852,6 +828,9 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev) else v4l2_device_unregister_subdev(subdev); +error_subdev_finalize: + v4l2_subdev_cleanup(subdev); + error_media_entity: media_entity_cleanup(&subdev->entity); @@ -868,5 +847,7 @@ void sun6i_csi_bridge_cleanup(struct sun6i_csi_device *csi_dev) v4l2_device_unregister_subdev(subdev); + v4l2_subdev_cleanup(subdev); + media_entity_cleanup(&subdev->entity); } diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h index 44653b38f722..a5b0a6f064dd 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h @@ -42,20 +42,11 @@ struct sun6i_csi_bridge { struct v4l2_subdev subdev; struct v4l2_async_notifier notifier; struct media_pad pads[2]; - struct v4l2_mbus_framefmt mbus_format; - struct mutex lock; /* Mbus format lock. */ struct sun6i_csi_bridge_source source_parallel; struct sun6i_csi_bridge_source source_mipi_csi2; }; -/* Helpers */ - -void sun6i_csi_bridge_dimensions(struct sun6i_csi_device *csi_dev, - unsigned int *width, unsigned int *height); -void sun6i_csi_bridge_format(struct sun6i_csi_device *csi_dev, - u32 *mbus_code, u32 *field); - /* Format */ const struct sun6i_csi_bridge_format * diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index 65879f4802c0..d90abba21309 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -888,14 +888,19 @@ static int sun6i_csi_capture_link_validate(struct media_link *link) media_entity_to_video_device(link->sink->entity); struct sun6i_csi_device *csi_dev = video_get_drvdata(video_dev); struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev; + struct v4l2_subdev *src_subdev = + media_entity_to_v4l2_subdev(link->source->entity); const struct sun6i_csi_capture_format *capture_format; const struct sun6i_csi_bridge_format *bridge_format; unsigned int capture_width, capture_height; - unsigned int bridge_width, bridge_height; const struct v4l2_format_info *format_info; + struct v4l2_subdev_format src_fmt = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = link->source->index + }; u32 pixelformat, capture_field; - u32 mbus_code, bridge_field; bool match; + int ret; sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height); @@ -904,19 +909,22 @@ static int sun6i_csi_capture_link_validate(struct media_link *link) if (WARN_ON(!capture_format)) return -EINVAL; - sun6i_csi_bridge_dimensions(csi_dev, &bridge_width, &bridge_height); + /* Resolve csi bridge format. */ + ret = v4l2_subdev_call(src_subdev, pad, get_fmt, NULL, &src_fmt); + if (ret) + return ret; - sun6i_csi_bridge_format(csi_dev, &mbus_code, &bridge_field); - bridge_format = sun6i_csi_bridge_format_find(mbus_code); + bridge_format = sun6i_csi_bridge_format_find(src_fmt.format.code); if (WARN_ON(!bridge_format)) return -EINVAL; /* No cropping/scaling is supported. */ - if (capture_width != bridge_width || capture_height != bridge_height) { + if (capture_width != src_fmt.format.width || + capture_height != src_fmt.format.height) { v4l2_err(v4l2_dev, "invalid input/output dimensions: %ux%u/%ux%u\n", - bridge_width, bridge_height, capture_width, - capture_height); + src_fmt.format.width, src_fmt.format.height, + capture_width, capture_height); return -EINVAL; } @@ -947,7 +955,8 @@ static int sun6i_csi_capture_link_validate(struct media_link *link) /* With raw input mode, we need a 1:1 match between input and output. */ if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW || capture_format->input_format_raw) { - match = sun6i_csi_capture_format_match(pixelformat, mbus_code); + match = sun6i_csi_capture_format_match(pixelformat, + src_fmt.format.code); if (!match) goto invalid; } From patchwork Sun Jul 19 11:27:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arash Golgol X-Patchwork-Id: 2689 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10]) by mxe881.netcup.net (Postfix) with ESMTPS id E15FA1C338B for ; Sun, 19 Jul 2026 09:57:45 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.234.253.10) smtp.mailfrom=linux-sunxi+bounces-24519-noreply=patchwork.local@lists.linux.dev smtp.helo=sea.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.234.253.10 as permitted sender) client-ip=172.234.253.10; envelope-from=linux-sunxi+bounces-24519-noreply=patchwork.local@lists.linux.dev; helo=sea.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sea.lore.kernel.org (Postfix) with ESMTP id 2980C300DF7B for ; Sun, 19 Jul 2026 07:57:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8BF3D2EDD6C; Sun, 19 Jul 2026 07:57:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WydQgQUz" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 183BC346ADC for ; Sun, 19 Jul 2026 07:57:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784447861; cv=none; b=qH/XhC0zynLd08xZYuhlAWmg37z+To4pvZDuA4bRwVf/zB+uGs//g9z7syHZZ2w6aWGG2DHUGq/fMdI7IfII4IhO7zlIhdqYMMDhfa6imKF6csCWPY6m6aBGdtunsO0mF8oPjlGH6f8+AmBU6lD+Gst1SaQgUi8p1/3SzxBU7VI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784447861; c=relaxed/simple; bh=ZHRVZhPzlyp+x7ruhcCcGaCk7KkIkLpi8O5C2Fboo1M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eM3G3Gd8dpOgOajrCafujQqIJk+2+2x28lEndRjMwTs0WFN98chmrOFjc7qOYKBJVUYBeUP4amx+l8fKQMxGTt5jS7q3X/sENy4TUIiq0jijjbNOHDanGZlaJvyu8qqo/i3WWpx+kPTHZBpm9oLMAB6Vd8HgU0tT7kpoAv2+Nd4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WydQgQUz; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-5b28c91fba5so3254348e87.1 for ; Sun, 19 Jul 2026 00:57:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784447858; x=1785052658; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=9QbUYJZtIOWTqXjFT0yqfZhtKIKPSa7W9f9Fx5FbY2Q=; b=WydQgQUz3NT1qzl3flyewjJVdkNL2FUNnTiqrO0e/xmuXo0MkFIpRondplWJ2ehIYd xsD4lw53+jU2SMrWdle9mrZWevcPbBZum2FLSi8B3MgE7NoqDmVAILAIx/CO+fucQktK PCM1hYV57ZehFIZAEZvpE/D7alLqlx8LHpTqBosatcrScSpKKiGbgq1ssWVGNI+7Zoqk l9Ro0M02iSGrJmv/3N+1c7ITcNAnuNmJtXmUWsTuhYuDEAs2ZIImhS5PUPTF52wi9CmT YdXGFF++Ufdrc1knF4Gvk1hLtQNfoLclaD5ePjibB+76dDWJx0D3tFQlI5akOHFgBkBU gKxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784447858; x=1785052658; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=9QbUYJZtIOWTqXjFT0yqfZhtKIKPSa7W9f9Fx5FbY2Q=; b=q7gDfSYLshptvvYO7nHJpnZm8RpbDdRSLioHR8B+iBFNM+YQDiXbwprvFYGJfmTja0 /x6253FKtQwXlBC1Vq6dyUxBAz2SB6VQe+Ab8OpfiwL5X5qmgtjAnmP0Kiy0Q+lBwlZQ cwU78I4/oz6ZCVFSruxwCZ/YMx8CiHQx5K57Ux5ATESkY/9X/RdEbIsnVSvlKigMCcYs DoxOFm1FJAnwVERWPc4yYZgI+lxNpR8cci0mhkFZ5CsJULZkpUdAs+R/B5YXp91wIaSo pxFpnZmxQUrzfaMpLIN2ZNCBxSlb3Q76pD+GEIhSuvK9E1Ljf28t+qg73NykPz+MToO/ plZA== X-Forwarded-Encrypted: i=1; AHgh+RpRXwH+2hs85v1uT6DrSQ2kCCUhW85YgpqzLu8ORB+A2VAAINgfguU/hRAWX178hRCNMcxlSGZLzd/hGw==@lists.linux.dev X-Gm-Message-State: AOJu0YxMVJ1Th8IJhiD0y7dW4qDUWoutRThneSHuwoBKz2s3mkS1hjmT sERGNeGxmOyjEOjPfF6V2vRi963E6Mvrv8EcA6win61SFXI7gjZKMkns X-Gm-Gg: AfdE7cmwwt34fS7jDAQv9WoScx8aSmNU0rX2VFeo7PeT9R1x0vaimqhMcIdw4m7kXyU ooeoC4rCL47BtgTmZ0mt+g8dBipOTlVPDjKVCxaKyTOwDtyxlOGxr/z1VwxrSj2zDUAYsiyaX+5 pK5s3M8mq0f1jdtLC3VDZm96XwYQX0LPl6PQxwGFQ8Kds0W+RvQYx2JMjg1nmcpPeSNKZouvzlf jblxEQDSjRB64+M7JKSj0rA75A4Wc8FYWSMDw9+6hGzBwjXPIhHJbFBjROg1JBZ51234juJngO4 Sq2UywDf3Rpdij89d0fwePGXlrkkDpimvohsz1C48ARA+Sazo+zLbESuiXxdA9OfItz5ly4O4FG 3sF3wKls63MTDQqqQBtJ/s808QdK7DM0tTxe+ghK4LTa9p77xTcWWONL7fSxWogcM2ROuFDCBdj pScg4wLzPzMLqaAnGCGn3qHX9LSMZ4lL5sijqEig+/YTznik53R7NfhMvkFxg= X-Received: by 2002:a05:6512:6412:b0:5b1:5e19:c496 with SMTP id 2adb3069b0e04-5b28a17760bmr2314551e87.14.1784447857959; Sun, 19 Jul 2026 00:57:37 -0700 (PDT) Received: from thinkpad ([5.212.61.200]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b291e0e926sm1604207e87.54.2026.07.19.00.57.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 00:57:36 -0700 (PDT) From: Arash Golgol To: linux-media@vger.kernel.org Cc: yong.deng@magewell.com, paulk@sys-base.io, mchehab@kernel.org, wens@kernel.org, jernej.skrabec@gmail.com, samuel@sholland.org, laurent.pinchart@ideasonboard.com, linux-sunxi@lists.linux.dev, Arash Golgol Subject: [PATCH v5 2/2] media: sun6i-csi: capture: Implement vidioc_enum_framesizes Date: Sun, 19 Jul 2026 14:57:14 +0330 Message-Id: <20260719112714.72802-3-arash.golgol@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260719112714.72802-1-arash.golgol@gmail.com> References: <20260719112714.72802-1-arash.golgol@gmail.com> Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-0.16 / 15.00]; BAYES_HAM(-5.50)[100.00%]; RBL_SENDERSCORE(2.00)[172.234.253.10:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; DATE_IN_FUTURE(0.50)[3]; R_MISSING_CHARSET(0.50)[]; MAILLIST(-0.15)[generic]; BAD_REP_POLICIES(0.10)[]; MIME_GOOD(-0.10)[text/plain]; HAS_LIST_UNSUB(-0.01)[]; PRECEDENCE_BULK(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; TAGGED_RCPT(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sea.lore.kernel.org:rdns,sea.lore.kernel.org:helo]; FREEMAIL_CC(0.00)[magewell.com,sys-base.io,kernel.org,gmail.com,sholland.org,ideasonboard.com,lists.linux.dev]; FUZZY_BLOCKED(0.00)[rspamd.com]; FORGED_SENDER_MAILLIST(0.00)[]; FROM_HAS_DN(0.00)[]; RCVD_COUNT_FIVE(0.00)[6]; ASN(0.00)[asn:63949, ipnet:172.234.224.0/19, country:SG]; R_SPF_ALLOW(0.00)[+ip4:172.234.253.10]; RCPT_COUNT_SEVEN(0.00)[10]; FREEMAIL_FROM(0.00)[gmail.com]; TO_DN_SOME(0.00)[]; FROM_NEQ_ENVFROM(0.00)[arashgolgol@gmail.com,linux-sunxi@lists.linux.dev]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; RCVD_TLS_LAST(0.00)[]; MIME_TRACE(0.00)[0:+]; TAGGED_FROM(0.00)[bounces-24519-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: E15FA1C338B X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= Report the stepwise frame size range supported by the CSI capture hardware for the pixel formats exposed by the driver. The hardware does not perform scaling and accepts any even width and height within the reported limits. Signed-off-by: Arash Golgol --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c index d90abba21309..e17c7f82ff47 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c @@ -738,6 +738,33 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv, return 0; } +static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + if (fsize->index) + return -EINVAL; + + /* Only accept format in map table. */ + if (!sun6i_csi_capture_format_find(fsize->pixel_format)) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN; + fsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX; + fsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN; + fsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX; + + if (fsize->pixel_format == V4L2_PIX_FMT_NV12_16L16) { + fsize->stepwise.step_width = 16; + fsize->stepwise.step_height = 16; + } else { + fsize->stepwise.step_width = 2; + fsize->stepwise.step_height = 2; + } + + return 0; +} + static int sun6i_csi_capture_g_fmt(struct file *file, void *priv, struct v4l2_format *format) { @@ -805,6 +832,7 @@ static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = { .vidioc_querycap = sun6i_csi_capture_querycap, .vidioc_enum_fmt_vid_cap = sun6i_csi_capture_enum_fmt, + .vidioc_enum_framesizes = sun6i_csi_capture_enum_framesize, .vidioc_g_fmt_vid_cap = sun6i_csi_capture_g_fmt, .vidioc_s_fmt_vid_cap = sun6i_csi_capture_s_fmt, .vidioc_try_fmt_vid_cap = sun6i_csi_capture_try_fmt,