From patchwork Fri Jul 17 16:05:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arash Golgol X-Patchwork-Id: 2683 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4]) by mxe881.netcup.net (Postfix) with ESMTPS id 0805D1C2EA9 for ; Fri, 17 Jul 2026 18:09:29 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 104.64.211.4) smtp.mailfrom=linux-sunxi+bounces-24504-noreply=patchwork.local@lists.linux.dev smtp.helo=sin.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 104.64.211.4 as permitted sender) client-ip=104.64.211.4; envelope-from=linux-sunxi+bounces-24504-noreply=patchwork.local@lists.linux.dev; helo=sin.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sin.lore.kernel.org (Postfix) with ESMTP id 745763018327 for ; Fri, 17 Jul 2026 16:06:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C4AEC36E460; Fri, 17 Jul 2026 16:06:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GfoVcB44" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (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 90521348C5E for ; Fri, 17 Jul 2026 16:06:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784304367; cv=none; b=u2G65l0JjC77nT6rmp5fMCfLH4udpTQAQiznUNkepcqupbX6KAyZ2YLGGjukabMYJsR6MrmBpvMDsqw1bgsioXipTokG/irU9Lphw3ne/MsMiw3ebvHCglIDY/+x2bOJ420+Veo6r5VZ8ad9daIbquYEUVLgt56RCDN45uLZNZs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784304367; c=relaxed/simple; bh=MHFzYqIGRj106kkMhEdJylVQ1UEZIPIkqE1sIJBWJzk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TssPVaRam2jZmFEypA+oiV7zWiaAU+bUODN9BKhG/n6qbkWgZTnLEJJJNLG/mhwGnCoZrOyo5+7uLAE33vuATVKKpiIsJbtHcq1eF0j1mxzzmFUSjKclLAid2Oi95fddw7SISLIRygikGpp9010G3OpMU4rQJOrQXlXHGZSmIFY= 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=GfoVcB44; arc=none smtp.client-ip=209.85.208.172 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-f172.google.com with SMTP id 38308e7fff4ca-3997a448ecbso47481881fa.0 for ; Fri, 17 Jul 2026 09:06:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784304363; x=1784909163; 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=GfoVcB44WpH3lDzdHKBe1LDgnh3049+df4hgBq8eYJYalupDbh/7Ns/8j5RocKN+Jb zNpflCstp4UMaKL5qq4kaWtmBh1LvB42Osi0QEXhfW7cUv3OWLBl5ksHgjpEkKg/lIsY qpj0pUyPHGexNgBH1IHRh7Kn+TfhMJmRAGCkTVojFlRk9Mj7r8YuofhpSJSlRwZBF9MV gPEoPWcvjQRUH5oC7Hqma+409ncyMmxebiHgt80AT6yRwGI3en/j0/WI3zwuOG9tqR1q Xwcpgu2+aLZtAQMPGfKnThtw5BL4lMQ7+TFgvVBw5CCBvH1/7B+81pnYqur92p3Gm9nT efYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784304363; x=1784909163; 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=nGe0eDRx0dU4n4OUqTha83dyAf4UTgY8wLKrXEDvY8l5NxVIaSRYmiOhxCgIghD70j YchQZ55uR0KH0/QuVuoTOJRfcaB5HbWl8pRxzsxmifF8gXVLs8z4hWw/Gi3L7VpC+vQf ASFfimL6KUKygGJ+j2UZMxqzSw21EZgKfex9GUOTy3A7+teSsgMtsfevfjZqqrnSqxUm GUn5KQRbeAHA4eX6ruWj8tJGsg1OvdEEP+V64WS2gGDpoMEt8dYsnE2q5rKr0Il6CVJI s+vDIm8imahcSR0j4ASMbdKtE6S/R8l530dhUhf2YsWLsq5ahc467hC/n31Mxaxewsd3 PALw== X-Forwarded-Encrypted: i=1; AHgh+RqqDsN9rVHgSXGEpcShrlnqUOTEhqOzuiWvC85iUU/3tu88x29EmWPT8wi/4FadacTx5CVrmTXQPYBEQg==@lists.linux.dev X-Gm-Message-State: AOJu0YyhLvuvbS9/3AW/WpgmXakaGKichYw7I23ni7SfjgUyQ9l5hIbS wyQVuqxyeTuKUZekNDuW3JHFtlyWefLnqf+IrUNxkLZ4+mrz3itDoYi/ X-Gm-Gg: AfdE7cm6gqMr/lSbx1w4HeeH/L+P9xNrplAv4w+Ll5c6GHxdCDAi0krdh4arxW/t2D4 ci/aO+D/KC3+LUCEDRrZx0WidoC9Z1EW9P6lvjUUrWjHo6/1tU7O8BBuxQWvPXqJ/CtPJqJcsVQ FGQxr0DfXBDW86v18hpt/5nZG+IjeDVb+GR65J/wHkVQTUsq0vRFq8IXEhg1vg5i7aKLV6U9zAh 5opwC9U3uEHLJFGiLZ0WwYFvJaCpDEOdHJoqc/SUL0ddvsPIRaENj68A28CCnxfMMZqnKkZAEmi npgykKIhGi1SG859RO2tmJuUlTGmBE/eNdhi34ihU1thBun4zDtAhEAJQf5mDQlXWBE9vzcq2ds J3hGWrl1EfYVVB8OsBRzEw2pFkv6cb5ual3aUtwNjeuvwAjh9HG+kAXEKVU+nInKbaKgz1+9Lkn y/aXZQSjw+Ipf7SZU9Z8c4qtydhqj1v9gR+pRsaPlAHosz+ua+4mqwV1GNgbAE X-Received: by 2002:a2e:bc82:0:b0:39b:d76:5cac with SMTP id 38308e7fff4ca-39eb28bf364mr6557521fa.29.1784304362411; Fri, 17 Jul 2026 09:06:02 -0700 (PDT) Received: from thinkpad ([5.215.185.239]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-39eb4ff8fa2sm2703911fa.31.2026.07.17.09.06.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jul 2026 09:06:01 -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 v4 1/2] media: sun6i-csi: bridge: Use V4L2 subdev active state Date: Fri, 17 Jul 2026 19:35:46 +0330 Message-Id: <20260717160547.44460-2-arash.golgol@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260717160547.44460-1-arash.golgol@gmail.com> References: <20260717160547.44460-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 [4.84 / 15.00]; RBL_SENDERSCORE(2.00)[104.64.211.4:from]; SUSPICIOUS_RECIPS(1.50)[]; DMARC_POLICY_SOFTFAIL(1.00)[gmail.com : SPF not aligned (relaxed), No valid DKIM,none]; 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)[sin.lore.kernel.org:rdns,sin.lore.kernel.org:helo,sys-base.io:email,ideasonboard.com: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:104.64.192.0/19, country:SG]; R_SPF_ALLOW(0.00)[+ip4:104.64.211.4]; 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-24504-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 0805D1C2EA9 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 Signed-off-by: Arash Golgol --- .../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 Fri Jul 17 16:05:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arash Golgol X-Patchwork-Id: 2682 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 1C99E1C2EA9 for ; Fri, 17 Jul 2026 18:09:10 +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-24505-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-24505-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 BA14730432E3 for ; Fri, 17 Jul 2026 16:06:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 011CF37CD2C; Fri, 17 Jul 2026 16:06:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="I4lsbDwr" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (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 F064E372066 for ; Fri, 17 Jul 2026 16:06:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784304373; cv=none; b=Y3gZssEEZg2E6TrydL0vvl0QN1E9pjNxfkQMFdViMwMse4YcD9T1lJM/1c5FExNumWBMIA3Y4KJpWsc/7FvojrTK70ImwIPiL+nc3eyvpx/ng2rberxw7uuCR1dJPVUBLQENUNCLerCckSFcTykVdsfWoJ8HSM57wRrBpq9csKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784304373; c=relaxed/simple; bh=H1k0d5nueQY2kXWjFqFdXAC+193REXYAdbNl4ofy6dQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JXg2qMbHUa6QgKy/6183aZQUOIdUsBUTcm4PfzhXABWdpaitvq30mk8vycL6WlgCGYF+aHLwBeo2tcDlbS7jn473VDLOgD491O/TmIXJdl1DHPcU86RDqzbzu5Vj6Q+2r3/CmKQlKGO5IM3jWdbGNesRrV5ltpAnim0dVxaBSjo= 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=I4lsbDwr; arc=none smtp.client-ip=209.85.167.53 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-f53.google.com with SMTP id 2adb3069b0e04-5aeba09900bso3570932e87.2 for ; Fri, 17 Jul 2026 09:06:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784304370; x=1784909170; 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=toQ9yiBWtG+Up1Zylcu9tHLCyoLfcGQvSFRzIedvl6s=; b=I4lsbDwrVFwl63itlAJOYTbT0AgMv2oj2kfLDx8KVp53RieMKq387VC41qPjwKwJJp hbhxgrX4JSS3kobj22fde7r6vTe8N5OttY7GTV+2hykMHCyqetg506TkXkWdIdmBB2Zm SoK/97pKRXZoKU0+vL8dx0hLp5VKYZgZKSalohQWAnhyA/AtLRI3ZQ9xIbBQ73n04Hab dcZaKV4l1Gctzd42RDA94UozLXk4NDN86p7Qzaow42A1fj09XxQd2JSv9Fyg4QSsKaK4 gBfWjRCYWfkh4XN163dFBYThGU8yDmgzJ0rGgQwe0SvsfFXCc7TXemCHV1Agi74TzhLG nWwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784304370; x=1784909170; 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=toQ9yiBWtG+Up1Zylcu9tHLCyoLfcGQvSFRzIedvl6s=; b=FUCmNdNinQYnzMYdUdc6IfADHRXqXAtzTPyNBkGB4g0zkcRuoNsXyedMFml7/FKXIY s2I1x67vwr7D6YwNsj0vjnEhJQQGQiugANgutcQ1d4ZnoXtgGNi3kQPYpGOjnRTV5vGu hYyVsXpliXux2khyQmUUsg4PqFHWf8GXR1CRwTEdXH04ocRhzaRdQhG940wRI8+PtOWd ryYJxGa61oVfIw4SaUnsLlZXLlEBUkDQZl2ZngAygDK050rC5DKbdq6Ujql+NOC2V9wW +jwFWmYnwO4yfNVcgGA0DmdHfH/KI+ldWaST2nOXs/EukOx4CMl5mqX31mH0jbMq6pje k59g== X-Forwarded-Encrypted: i=1; AHgh+Rq063Diq/a8Sg5snldoNyXo3ea1wqj2H82hVO81791gp19CokSz8p/pBLy7zPNncMYIBG9+XwHz5P+R6Q==@lists.linux.dev X-Gm-Message-State: AOJu0YwP0+IeGrSNj8Dr1RjR8Darty4jTYX3PTOQ2OUNDvTnXNRSoArn 5dmCHRSZc4bf4nhY9604ql/pPodPGgdImean/6y+rksY3+4LJHS1QkfU X-Gm-Gg: AfdE7ckynEZT1W2nPHJJkrfWie44TtyAqmtQD6D66EkkXrcPpi0C35iZcgSan11EuY/ Ma8wpISk2xOD9O2Jz6Hd8jT3kvHji89f0xzyPVoC8qouwYXJ+B8FGV55so2ro3tDz2pm6nD5C/j k01kbUf4DfZd9QweNf+imaooBkP74OvJnHZrZdVz03yHg/tlhvmRpN4gNxVkjbVNEA09VvhYn0N TdffxjD2Ke+txFmNfUDsfacoWSV6pRRduuHcff1y2hsmesv0oMSQu5z+lKaBdvyg8GEnWfKEAVL 35uWIeo+Ti473c0cblmsts49+HdgjbVimBNLLZm7deNAYs5TzJnHMaydUV4gkhHvDUYnOxUVKlz rEbs/PVnL6bNjp2KMmHFFTAyNgfLBarakYxZVziETH7zfrYd9N7Oz2f7qd0eHNko23xA0V6RN7Q xfvxyMjvfdKQlNTUtheuezCi+zziM4+RqGBowN1S7JluvXLZMuukJjFdJrrTSf X-Received: by 2002:a05:6512:15a3:b0:5ae:c27b:f7a0 with SMTP id 2adb3069b0e04-5b28f8551f1mr764576e87.11.1784304369207; Fri, 17 Jul 2026 09:06:09 -0700 (PDT) Received: from thinkpad ([5.215.185.239]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5b291daf111sm454996e87.37.2026.07.17.09.06.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jul 2026 09:06:08 -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 v4 2/2] media: sun6i-csi: capture: Implement vidioc_enum_framesizes Date: Fri, 17 Jul 2026 19:35:47 +0330 Message-Id: <20260717160547.44460-3-arash.golgol@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260717160547.44460-1-arash.golgol@gmail.com> References: <20260717160547.44460-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.66 / 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]; R_MISSING_CHARSET(0.50)[]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; FUZZY_BLOCKED(0.00)[rspamd.com]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; FORGED_SENDER_MAILLIST(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[sea.lore.kernel.org:rdns,sea.lore.kernel.org:helo,ideasonboard.com:email]; PRECEDENCE_BULK(0.00)[]; FREEMAIL_CC(0.00)[magewell.com,sys-base.io,kernel.org,gmail.com,sholland.org,ideasonboard.com,lists.linux.dev]; TAGGED_RCPT(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-24505-noreply=patchwork.local]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[] X-Rspamd-Queue-Id: 1C99E1C2EA9 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 Reviewed-by: Paul Kocialkowski Tested-by: Paul Kocialkowski Reviewed-by: Laurent Pinchart --- .../sunxi/sun6i-csi/sun6i_csi_capture.c | 22 +++++++++++++++++++ 1 file changed, 22 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..f788b4234673 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,27 @@ 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; + 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 +826,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,