From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4003339710; Thu, 30 Oct 2025 08:43:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813798; cv=none; b=mH+oWB9XhSDsWfLXIrU8RB7c+kV1NBEJ/ZDgIlBw8s4IHLEMDLMJEY5H3NbdtxlryUjLSC2F3lRih9crbg9HuRFYiUc8VmbvxuUrcGnoyqWnB5uLvCQuQpQyQqLZxkRj9+v6k2t4GPDdr174PR7jkD9t9x/gDRkzTV7C60KLtwg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813798; c=relaxed/simple; bh=f554b4UEqiVHHa37Elp5PwAy1JMUtZkiY0I7rFW4grc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=HP9/2Mi0s8w1+WQZ/EjIXJ5Vm5CiCM7069y5Q9AkvfBSj03+qIZ+0CcxfIG5c5IEV1Kr+t/Hp5UEJJYzKdYnX846Lh+ZC3NVTL1/2IPlkbdNp9LDmIlWI5ZjeLf20Ngpk4VryLoZzz1svzBlRHhFWC/Th5+QmXMymJoZvwHAm4I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=oFQqK4Vp; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oFQqK4Vp" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C1258EAE; Thu, 30 Oct 2025 09:41:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813684; bh=f554b4UEqiVHHa37Elp5PwAy1JMUtZkiY0I7rFW4grc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oFQqK4VpPOVJvFfNodFiRl4n8cX4Ew8UkX8Mmo95fDPTDnQbwqKcw/1Sn4Y6oFKW9 wK+ROQ2BFzf0nyOLCarVUsGh8fh/NAYvXqnyY8NB+b06V8Talcx1sZ+SrL3nzQH5eB farA24Kgd1CIpniO9z36tzeidBIVWORebiSDOp2o= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Tommaso Merciai , Jai Luthra Subject: [PATCH v4 1/8] media: imx335: Rectify name of mode struct Date: Thu, 30 Oct 2025 14:12:54 +0530 Message-ID: <20251030-imx335_binning-v4-1-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Umang Jain In commit 81495a59baeb ("media: imx335: Fix active area height discrepency") the height for the mode struct was rectified to '1944'. However, the name of mode struct is still reflecting to '1940'. Update it. Signed-off-by: Umang Jain Reviewed-by: Tommaso Merciai Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index c043df2f15fb25b3a56422092f99a1fd9a508fa9..213cfb7276611f522db0643186f= 25a8fef3c39db 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -252,7 +252,7 @@ static const int imx335_tpg_val[] =3D { }; =20 /* Sensor mode registers */ -static const struct cci_reg_sequence mode_2592x1940_regs[] =3D { +static const struct cci_reg_sequence mode_2592x1944_regs[] =3D { { IMX335_REG_MODE_SELECT, IMX335_MODE_STANDBY }, { IMX335_REG_MASTER_MODE, 0x00 }, { IMX335_REG_WINMODE, 0x04 }, @@ -416,8 +416,8 @@ static const struct imx335_mode supported_mode =3D { .vblank_max =3D 133060, .pclk =3D 396000000, .reg_list =3D { - .num_of_regs =3D ARRAY_SIZE(mode_2592x1940_regs), - .regs =3D mode_2592x1940_regs, + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_regs), + .regs =3D mode_2592x1944_regs, }, }; =20 --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23D37339710; Thu, 30 Oct 2025 08:43:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813804; cv=none; b=bLJMK/RARqQPNPsi7yCo6UDsgih8Fc1q48XwLVtnr9e8HloGv/PGk+NYRpeulhe3+MyxT1Fk8ycwvxkJog6hn/sB5BGZ4CO0zCo1ep98iCuBTEV4NMSPMcEqZ56YU89yWps8WOqvusSXta4VJoSu3Ih+ebh/3S488XeeImk201s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813804; c=relaxed/simple; bh=sd1KQ1+sgWDWcV767PO/vpaB3KRD7rWOEUgDjKTJ1e8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=p3D4YugrjdXpYPSik+z+hhEKTHHCRLPM/XLPsxIqK5U47UDCCraxrc837qnrikP+2RBbCP1Eb3Q6XBq6N2HVmERo+v1fRy7uZWgTBIZjN7Ptzs7Ij8zrnBgOBUYL1txOY7n9P02r97rLYZwO30SBgvutCf97CRHcT9AW2sW2xtw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=WYNGDs0b; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WYNGDs0b" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8B014EAE; Thu, 30 Oct 2025 09:41:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813691; bh=sd1KQ1+sgWDWcV767PO/vpaB3KRD7rWOEUgDjKTJ1e8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WYNGDs0bNghI8nWLNrLhcR6ubWJdGBgHJHxD52NC0c4te/RDVa/y+4HlaUElGLm9d Qfn9Ywnj0g2/sLstRurBr4/l4exrPQk2Cd6jBAZxIPhAd8KF3G2aH2/KlC0KZHTCDh wCSmblfCg2ny96VGqCYCIb4vzvfYNP5g4/nT7FTU= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Tommaso Merciai , Jai Luthra Subject: [PATCH v4 2/8] media: imx335: Support vertical flip Date: Thu, 30 Oct 2025 14:12:55 +0530 Message-ID: <20251030-imx335_binning-v4-2-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable From: Umang Jain Support vertical flip by setting REG_VREVERSE. Additional registers also needs to be set per mode, according to the readout direction (normal/inverted) as mentioned in the data sheet. Since the register IMX335_REG_AREA3_ST_ADR_1 is based on the flip (and is set via vflip related registers), it has been moved out of the 2592x1944 mode regs. Signed-off-by: Umang Jain Reviewed-by: Tommaso Merciai Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 64 ++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 213cfb7276611f522db0643186f25a8fef3c39db..770adc3106321769823f757d0d3= 277d1948a6bc2 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -56,6 +56,9 @@ #define IMX335_AGAIN_STEP 1 #define IMX335_AGAIN_DEFAULT 0 =20 +/* Vertical flip */ +#define IMX335_REG_VREVERSE CCI_REG8(0x304f) + #define IMX335_REG_TPG_TESTCLKEN CCI_REG8(0x3148) =20 #define IMX335_REG_INCLKSEL1 CCI_REG16_LE(0x314c) @@ -155,6 +158,8 @@ static const char * const imx335_supply_name[] =3D { * @vblank_max: Maximum vertical blanking in lines * @pclk: Sensor pixel clock * @reg_list: Register list for sensor mode + * @vflip_normal: Register list vflip (normal readout) + * @vflip_inverted: Register list vflip (inverted readout) */ struct imx335_mode { u32 width; @@ -166,6 +171,8 @@ struct imx335_mode { u32 vblank_max; u64 pclk; struct imx335_reg_list reg_list; + struct imx335_reg_list vflip_normal; + struct imx335_reg_list vflip_inverted; }; =20 /** @@ -183,6 +190,7 @@ struct imx335_mode { * @pclk_ctrl: Pointer to pixel clock control * @hblank_ctrl: Pointer to horizontal blanking control * @vblank_ctrl: Pointer to vertical blanking control + * @vflip: Pointer to vertical flip control * @exp_ctrl: Pointer to exposure control * @again_ctrl: Pointer to analog gain control * @vblank: Vertical blanking in lines @@ -207,6 +215,7 @@ struct imx335 { struct v4l2_ctrl *pclk_ctrl; struct v4l2_ctrl *hblank_ctrl; struct v4l2_ctrl *vblank_ctrl; + struct v4l2_ctrl *vflip; struct { struct v4l2_ctrl *exp_ctrl; struct v4l2_ctrl *again_ctrl; @@ -259,7 +268,6 @@ static const struct cci_reg_sequence mode_2592x1944_reg= s[] =3D { { IMX335_REG_HTRIMMING_START, 48 }, { IMX335_REG_HNUM, 2592 }, { IMX335_REG_Y_OUT_SIZE, 1944 }, - { IMX335_REG_AREA3_ST_ADR_1, 176 }, { IMX335_REG_AREA3_WIDTH_1, 3928 }, { IMX335_REG_OPB_SIZE_V, 0 }, { IMX335_REG_XVS_XHS_DRV, 0x00 }, @@ -333,6 +341,26 @@ static const struct cci_reg_sequence mode_2592x1944_re= gs[] =3D { { CCI_REG8(0x3a00), 0x00 }, }; =20 +static const struct cci_reg_sequence mode_2592x1944_vflip_normal[] =3D { + { IMX335_REG_AREA3_ST_ADR_1, 176 }, + + /* Undocumented V-Flip related registers on Page 55 of datasheet. */ + { CCI_REG8(0x3081), 0x02, }, + { CCI_REG8(0x3083), 0x02, }, + { CCI_REG16_LE(0x30b6), 0x00 }, + { CCI_REG16_LE(0x3116), 0x08 }, +}; + +static const struct cci_reg_sequence mode_2592x1944_vflip_inverted[] =3D { + { IMX335_REG_AREA3_ST_ADR_1, 4112 }, + + /* Undocumented V-Flip related registers on Page 55 of datasheet. */ + { CCI_REG8(0x3081), 0xfe, }, + { CCI_REG8(0x3083), 0xfe, }, + { CCI_REG16_LE(0x30b6), 0x1fa }, + { CCI_REG16_LE(0x3116), 0x002 }, +}; + static const struct cci_reg_sequence raw10_framefmt_regs[] =3D { { IMX335_REG_ADBIT, 0x00 }, { IMX335_REG_MDBIT, 0x00 }, @@ -419,6 +447,14 @@ static const struct imx335_mode supported_mode =3D { .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_regs), .regs =3D mode_2592x1944_regs, }, + .vflip_normal =3D { + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_normal), + .regs =3D mode_2592x1944_vflip_normal, + }, + .vflip_inverted =3D { + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_inverted), + .regs =3D mode_2592x1944_vflip_inverted, + }, }; =20 /** @@ -492,6 +528,19 @@ static int imx335_update_exp_gain(struct imx335 *imx33= 5, u32 exposure, u32 gain) return ret; } =20 +static int imx335_update_vertical_flip(struct imx335 *imx335, u32 vflip) +{ + const struct imx335_reg_list * const vflip_regs =3D + vflip ? &imx335->cur_mode->vflip_inverted : + &imx335->cur_mode->vflip_normal; + int ret =3D 0; + + cci_multi_reg_write(imx335->cci, vflip_regs->regs, + vflip_regs->num_of_regs, &ret); + + return cci_write(imx335->cci, IMX335_REG_VREVERSE, vflip, &ret); +} + static int imx335_update_test_pattern(struct imx335 *imx335, u32 pattern_i= ndex) { int ret =3D 0; @@ -593,6 +642,10 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl) =20 ret =3D imx335_update_exp_gain(imx335, exposure, analog_gain); =20 + break; + case V4L2_CID_VFLIP: + ret =3D imx335_update_vertical_flip(imx335, ctrl->val); + break; case V4L2_CID_TEST_PATTERN: ret =3D imx335_update_test_pattern(imx335, ctrl->val); @@ -1175,7 +1228,7 @@ static int imx335_init_controls(struct imx335 *imx335) return ret; =20 /* v4l2_fwnode_device_properties can add two more controls */ - ret =3D v4l2_ctrl_handler_init(ctrl_hdlr, 9); + ret =3D v4l2_ctrl_handler_init(ctrl_hdlr, 10); if (ret) return ret; =20 @@ -1210,6 +1263,13 @@ static int imx335_init_controls(struct imx335 *imx33= 5) =20 v4l2_ctrl_cluster(2, &imx335->exp_ctrl); =20 + imx335->vflip =3D v4l2_ctrl_new_std(ctrl_hdlr, + &imx335_ctrl_ops, + V4L2_CID_VFLIP, + 0, 1, 1, 0); + if (imx335->vflip) + imx335->vflip->flags |=3D V4L2_CTRL_FLAG_MODIFY_LAYOUT; + imx335->vblank_ctrl =3D v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_VBLANK, --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7ACD338F5B; Thu, 30 Oct 2025 08:43:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813810; cv=none; b=ceqcVazKPgwxI2gfxLDyy+EGSRuPWDAIK+1VkjANrYXkBg6Fk4amp6wfD2Q5zdl1C8zo6QHjLc/Nr2rD9JlQbW8S9V4Tl0d5OZE7nsd98hd4HTmruR3jsmZ7PnjiQ1BnxODZKYcuy3L6qSikRT7e8xFjF5ZcZ/lxHXQLT1zACbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813810; c=relaxed/simple; bh=vREb5QGLlC+MfWhaXitSYjEqSFA17LTQdF1ZiG0e5dE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Mnqm/06GqmaJrJnHqDJx4nPEJjC3IGJjNZT/mVNfZkWVuNHRokOrFf+R6C7maDTgoGApoDHDt3xKzjfMPmaYkT/fDmJtKSLgnq+gPbOPEm+vwpnKbstEwm1xwbasiRVccsHU/48k26WT65V/V95sPlj0jD2DGn0erkUCd1rvQwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=KmyL0LEQ; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="KmyL0LEQ" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2DE3FEAE; Thu, 30 Oct 2025 09:41:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813697; bh=vREb5QGLlC+MfWhaXitSYjEqSFA17LTQdF1ZiG0e5dE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KmyL0LEQN7S2tjh33gXYiRpIKesw9OknqGTiDe12UqxHhItTheobmyB/4bqENdu3w Ru00Tt475ltPE+cw1Q1r9YMldTTDaQa3neK7DasQ24kNCdddnBHn+LTu0PjWgvWXNi vzIhJ7fqhRaoBomg93MEwfqT0jZGZDWUd2UHy+iY= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 3/8] media: imx335: Update the native pixel array width Date: Thu, 30 Oct 2025 14:12:56 +0530 Message-ID: <20251030-imx335_binning-v4-3-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The sensor datasheet reports actual total number of pixels as 2696x2044. This becomes important for supporting 2x2 binning modes that can go beyond the current maximum pixel array width set here. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 770adc3106321769823f757d0d3277d1948a6bc2..145b4415ba590245ab49c0124d8= 094683adddf0e 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -124,12 +124,20 @@ #define IMX335_NUM_DATA_LANES 4 =20 /* IMX335 native and active pixel array size. */ -#define IMX335_NATIVE_WIDTH 2616U -#define IMX335_NATIVE_HEIGHT 1964U -#define IMX335_PIXEL_ARRAY_LEFT 12U -#define IMX335_PIXEL_ARRAY_TOP 12U -#define IMX335_PIXEL_ARRAY_WIDTH 2592U -#define IMX335_PIXEL_ARRAY_HEIGHT 1944U +static const struct v4l2_rect imx335_native_area =3D { + .top =3D 0, + .left =3D 0, + .width =3D 2696, + .height =3D 2044, +}; + +static const struct v4l2_rect imx335_active_area =3D { + .top =3D 50, + .left =3D 52, + .width =3D 2592, + .height =3D 1944, +}; + =20 /** * struct imx335_reg_list - imx335 sensor register list @@ -862,21 +870,13 @@ static int imx335_get_selection(struct v4l2_subdev *s= d, { switch (sel->target) { case V4L2_SEL_TGT_NATIVE_SIZE: - sel->r.top =3D 0; - sel->r.left =3D 0; - sel->r.width =3D IMX335_NATIVE_WIDTH; - sel->r.height =3D IMX335_NATIVE_HEIGHT; - + sel->r =3D imx335_native_area; return 0; =20 case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_CROP_DEFAULT: case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.top =3D IMX335_PIXEL_ARRAY_TOP; - sel->r.left =3D IMX335_PIXEL_ARRAY_LEFT; - sel->r.width =3D IMX335_PIXEL_ARRAY_WIDTH; - sel->r.height =3D IMX335_PIXEL_ARRAY_HEIGHT; - + sel->r =3D imx335_active_area; return 0; } =20 --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69C3932D7FB; Thu, 30 Oct 2025 08:43:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813815; cv=none; b=nShBJ/U1yqEkj7szuF0AlPHVHX7HrCHVknsPYCSRdfKMdTS//8jHlVY3W9uxeMSh4HwN3mv7B7jny4Xo+olJIS3PGVku/jDi9Cc27WoE5RWXbxsqgOHpRRfMakX0E6RQKty8jNqyj7d9iy+BWx6Ebd7TKzpY+jq3iCMAeLeno6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813815; c=relaxed/simple; bh=8q8zjRMdQxgekD+7tRCl5Ed+AssG2njqN+QZF4x+aUU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sqmbuoZv6E58bJnqyfiz/rGTmD/VASlhKCVrtyD4nFYe9yDqX13xz0rw0CUWc3KSKaoKmv3whoUvPmKml73tuONbqBaXYbxG8MQlX6AbMzP/8laMU09yPGzWrsL48HS0dSHFx+HOMk9fRoqcfZL1RGohP/Beysvbvx05LP6eZaA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=MtviTo/R; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="MtviTo/R" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E50E1EAE; Thu, 30 Oct 2025 09:41:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813703; bh=8q8zjRMdQxgekD+7tRCl5Ed+AssG2njqN+QZF4x+aUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MtviTo/R51u4opv1in0gQiu2VpE6Gdach+o8n/DiUZKseHb4EdatjyvNHRdTQ8fNZ ab9XrdQP+M1zvNGeZVmUggidg8WZPdpct+wOunIPKj8V5xaeQcPDn967Ks5SOcTu/Z rvb7RwhuOK3rfcxuBW3u0x1lXlzyyWhtX20usqLo= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 4/8] media: imx335: Update HBLANK range on mode change Date: Thu, 30 Oct 2025 14:12:57 +0530 Message-ID: <20251030-imx335_binning-v4-4-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable While switching modes, updating to a different value of HBLANK isn't sufficient, as this is a read-only control with a single allowed value, and thus hblank_min =3D=3D hblank_max =3D=3D hblank of the default mode. So to correctly update the user-facing value of the HBLANK parameter, which is necessary for correct framerate calculation, update the whole range when switching modes. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 145b4415ba590245ab49c0124d8094683adddf0e..77863a28c4725ae151ac60213ab= 05a46bd1549ee 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -493,7 +493,8 @@ static int imx335_update_controls(struct imx335 *imx335, if (ret) return ret; =20 - ret =3D __v4l2_ctrl_s_ctrl(imx335->hblank_ctrl, mode->hblank); + ret =3D __v4l2_ctrl_modify_range(imx335->hblank_ctrl, mode->hblank, + mode->hblank, 1, mode->hblank); if (ret) return ret; =20 --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEF34334688; Thu, 30 Oct 2025 08:43:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813822; cv=none; b=pYy2GzAZ5vB75FdNR/uBxTJeRdVgf+JueozwdtUsxdh6hVetYad+4YomhyKTb38KYNw4WhgGeSDys1DMtYoOpxUqlhF8ItNU82rMhC3nAEBg02vWJ7tbIlxLo9282MmBl/kFYiBr/lQ708Yaku0w3g7F5Ic7j3MHuH71o0qBPUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813822; c=relaxed/simple; bh=DptlhcOCv/jEqQi8H1Qnjja+E+XZztRNKeEjDcwb0to=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P4+pJWVqGodn/POuivcw7mfqkASaL4HFU1+x4CgILPCik/nJCXwMwt3/hdI++1oNUz4Ko0S3qaLwd3JPHRcSfdhmR0xC5Tqr+Od/dr+9to1SHF7oIzt82pxreGgDWx5FnhSHdxmZwCE15nMNhArlT40zSnjH2rdYTlYu6yYB4Uc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=ZQhoRzoz; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZQhoRzoz" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 51B85EAE; Thu, 30 Oct 2025 09:41:49 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813709; bh=DptlhcOCv/jEqQi8H1Qnjja+E+XZztRNKeEjDcwb0to=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZQhoRzozdozkqobwZEG7sAV1jVq0Y3Bf5ufsrcw44qv9Tk81hfPEiMzWmSVEnfxCt r+S9osOCOvoUrD8trebtDmDhDtl2B8QlBTnYfCOcRx7t42W4xoDrPYUWMM/7N327Tm HPDaeHaZIRT/l7Um9t+gLSR/hwg6InDyOuOKblCs= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 5/8] media: imx335: Handle runtime PM in leaf functions Date: Thu, 30 Oct 2025 14:12:58 +0530 Message-ID: <20251030-imx335_binning-v4-5-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Simplify .s_stream callback implementation by moving the runtime PM calls to the leaf functions. This patch should not affect any functionality. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 51 ++++++++++++++++++++++--------------------= --------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 77863a28c4725ae151ac60213ab05a46bd1549ee..5e18eb998f9d76907ef88cd09ee= 19e7afe9166e4 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -912,13 +912,17 @@ static int imx335_start_streaming(struct imx335 *imx3= 35) const struct imx335_reg_list *reg_list; int ret; =20 + ret =3D pm_runtime_resume_and_get(imx335->dev); + if (ret < 0) + return ret; + /* Setup PLL */ reg_list =3D &link_freq_reglist[__ffs(imx335->link_freq_bitmap)]; ret =3D cci_multi_reg_write(imx335->cci, reg_list->regs, reg_list->num_of_regs, NULL); if (ret) { dev_err(imx335->dev, "%s failed to set plls\n", __func__); - return ret; + goto err_rpm_put; } =20 /* Write sensor mode registers */ @@ -927,27 +931,27 @@ static int imx335_start_streaming(struct imx335 *imx3= 35) reg_list->num_of_regs, NULL); if (ret) { dev_err(imx335->dev, "fail to write initial registers\n"); - return ret; + goto err_rpm_put; } =20 ret =3D imx335_set_framefmt(imx335); if (ret) { dev_err(imx335->dev, "%s failed to set frame format: %d\n", __func__, ret); - return ret; + goto err_rpm_put; } =20 /* Configure lanes */ ret =3D cci_write(imx335->cci, IMX335_REG_LANEMODE, imx335->lane_mode, NULL); if (ret) - return ret; + goto err_rpm_put; =20 /* Setup handler will write actual exposure and gain */ ret =3D __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler); if (ret) { dev_err(imx335->dev, "fail to setup handler\n"); - return ret; + goto err_rpm_put; } =20 /* Start streaming */ @@ -955,25 +959,29 @@ static int imx335_start_streaming(struct imx335 *imx3= 35) IMX335_MODE_STREAMING, NULL); if (ret) { dev_err(imx335->dev, "fail to start streaming\n"); - return ret; + goto err_rpm_put; } =20 /* Initial regulator stabilization period */ usleep_range(18000, 20000); =20 return 0; + +err_rpm_put: + pm_runtime_put(imx335->dev); + + return ret; } =20 /** * imx335_stop_streaming() - Stop sensor stream * @imx335: pointer to imx335 device - * - * Return: 0 if successful, error code otherwise. */ -static int imx335_stop_streaming(struct imx335 *imx335) +static void imx335_stop_streaming(struct imx335 *imx335) { - return cci_write(imx335->cci, IMX335_REG_MODE_SELECT, - IMX335_MODE_STANDBY, NULL); + cci_write(imx335->cci, IMX335_REG_MODE_SELECT, + IMX335_MODE_STANDBY, NULL); + pm_runtime_put(imx335->dev); } =20 /** @@ -986,30 +994,15 @@ static int imx335_stop_streaming(struct imx335 *imx33= 5) static int imx335_set_stream(struct v4l2_subdev *sd, int enable) { struct imx335 *imx335 =3D to_imx335(sd); - int ret; + int ret =3D 0; =20 mutex_lock(&imx335->mutex); =20 - if (enable) { - ret =3D pm_runtime_resume_and_get(imx335->dev); - if (ret) - goto error_unlock; - + if (enable) ret =3D imx335_start_streaming(imx335); - if (ret) - goto error_power_off; - } else { + else imx335_stop_streaming(imx335); - pm_runtime_put(imx335->dev); - } - - mutex_unlock(&imx335->mutex); =20 - return 0; - -error_power_off: - pm_runtime_put(imx335->dev); -error_unlock: mutex_unlock(&imx335->mutex); =20 return ret; --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CEFD933C52D; Thu, 30 Oct 2025 08:43:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813828; cv=none; b=UQeiWBFfmWro8Kd9ZLABWJzTJTUCFbxmM6Ie6TxfnIch7Yvu7WP9htk2bKcx8tMrBOf1QTn3ThXzoFl9A4JpqdNydjt5CtAoWzqZxI+MPchAERZeNwpwBjyYf+Ck9rt1hGcBa6p6Vd3q00xQwPfXiiWctqOxqvZ6Aq2P9oKCMW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813828; c=relaxed/simple; bh=kokEcIS5DxI8Kkdo0V1lHfdBi9YnPOXA5WgzvzYYTeY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PgRKQg/nTFcGuT9OvE4k6VpYsT/S9/Klq8fwokZyZOugvqgR5Lt+gzqeM+VCnDgijEYtEA0uhHgGNr/zRB7rnON8CjjF7RBfvBUhVo/icBpp2+bza9/oNhiLaiOqrj52Xe7UA74un/txG0zcwqeOD4LppgWb/PqFgen5zJhgJHc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=h9U3zq40; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="h9U3zq40" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1CE0FEAE; Thu, 30 Oct 2025 09:41:54 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813715; bh=kokEcIS5DxI8Kkdo0V1lHfdBi9YnPOXA5WgzvzYYTeY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h9U3zq40Ec2dFIcU+Dj3/hXJrEekmmFbFcFowaSpSqq6XDfJelnodSoToLhSlIVjz GwMtFwVly6FnSfesnvXhiGN0osADcs4wT1Tpnt41cDwREc32kHHHSBqkTAUBTSlzyx LB04hKoRByK5nt8LBKkmy/1CeqMQG8f41nEjLcDw= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 6/8] media: imx355: Use subdev active state Date: Thu, 30 Oct 2025 14:12:59 +0530 Message-ID: <20251030-imx335_binning-v4-6-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Port the driver to use the subdev active state. This simplifies locking, and makes it easier to support different crop sizes for binned modes, by storing the crop rectangle inside the subdev state. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 79 +++++++++++++++++++++---------------------= ------------------------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 5e18eb998f9d76907ef88cd09ee19e7afe9166e4..00e65da5f9ae127f6d61a0fe686= 91c9f49c26d15 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -204,7 +204,6 @@ struct imx335_mode { * @vblank: Vertical blanking in lines * @lane_mode: Mode for number of connected data lanes * @cur_mode: Pointer to current selected sensor mode - * @mutex: Mutex for serializing sensor controls * @link_freq_bitmap: Menu bitmap for link_freq_ctrl * @cur_mbus_code: Currently selected media bus format code */ @@ -231,7 +230,6 @@ struct imx335 { u32 vblank; u32 lane_mode; const struct imx335_mode *cur_mode; - struct mutex mutex; unsigned long link_freq_bitmap; u32 cur_mbus_code; }; @@ -759,36 +757,6 @@ static void imx335_fill_pad_format(struct imx335 *imx3= 35, fmt->format.xfer_func =3D V4L2_XFER_FUNC_NONE; } =20 -/** - * imx335_get_pad_format() - Get subdevice pad format - * @sd: pointer to imx335 V4L2 sub-device structure - * @sd_state: V4L2 sub-device configuration - * @fmt: V4L2 sub-device format need to be set - * - * Return: 0 if successful, error code otherwise. - */ -static int imx335_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct imx335 *imx335 =3D to_imx335(sd); - - mutex_lock(&imx335->mutex); - - if (fmt->which =3D=3D V4L2_SUBDEV_FORMAT_TRY) { - struct v4l2_mbus_framefmt *framefmt; - - framefmt =3D v4l2_subdev_state_get_format(sd_state, fmt->pad); - fmt->format =3D *framefmt; - } else { - imx335_fill_pad_format(imx335, imx335->cur_mode, fmt); - } - - mutex_unlock(&imx335->mutex); - - return 0; -} - /** * imx335_set_pad_format() - Set subdevice pad format * @sd: pointer to imx335 V4L2 sub-device structure @@ -802,12 +770,12 @@ static int imx335_set_pad_format(struct v4l2_subdev *= sd, struct v4l2_subdev_format *fmt) { struct imx335 *imx335 =3D to_imx335(sd); + struct v4l2_mbus_framefmt *format; const struct imx335_mode *mode; int i, ret =3D 0; =20 - mutex_lock(&imx335->mutex); - mode =3D &supported_mode; + for (i =3D 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) { if (imx335_mbus_codes[i] =3D=3D fmt->format.code) imx335->cur_mbus_code =3D imx335_mbus_codes[i]; @@ -815,19 +783,15 @@ static int imx335_set_pad_format(struct v4l2_subdev *= sd, =20 imx335_fill_pad_format(imx335, mode, fmt); =20 - if (fmt->which =3D=3D V4L2_SUBDEV_FORMAT_TRY) { - struct v4l2_mbus_framefmt *framefmt; + format =3D v4l2_subdev_state_get_format(sd_state, fmt->pad); + *format =3D fmt->format; =20 - framefmt =3D v4l2_subdev_state_get_format(sd_state, fmt->pad); - *framefmt =3D fmt->format; - } else { + if (fmt->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) { ret =3D imx335_update_controls(imx335, mode); if (!ret) imx335->cur_mode =3D mode; } =20 - mutex_unlock(&imx335->mutex); - return ret; } =20 @@ -847,12 +811,10 @@ static int imx335_init_state(struct v4l2_subdev *sd, fmt.which =3D sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTI= VE; imx335_fill_pad_format(imx335, &supported_mode, &fmt); =20 - mutex_lock(&imx335->mutex); __v4l2_ctrl_modify_range(imx335->link_freq_ctrl, 0, __fls(imx335->link_freq_bitmap), ~(imx335->link_freq_bitmap), __ffs(imx335->link_freq_bitmap)); - mutex_unlock(&imx335->mutex); =20 return imx335_set_pad_format(sd, sd_state, &fmt); } @@ -994,16 +956,17 @@ static void imx335_stop_streaming(struct imx335 *imx3= 35) static int imx335_set_stream(struct v4l2_subdev *sd, int enable) { struct imx335 *imx335 =3D to_imx335(sd); + struct v4l2_subdev_state *state; int ret =3D 0; =20 - mutex_lock(&imx335->mutex); + state =3D v4l2_subdev_lock_and_get_active_state(sd); =20 if (enable) ret =3D imx335_start_streaming(imx335); else imx335_stop_streaming(imx335); =20 - mutex_unlock(&imx335->mutex); + v4l2_subdev_unlock_state(state); =20 return ret; } @@ -1131,7 +1094,7 @@ static const struct v4l2_subdev_pad_ops imx335_pad_op= s =3D { .enum_frame_size =3D imx335_enum_frame_size, .get_selection =3D imx335_get_selection, .set_selection =3D imx335_get_selection, - .get_fmt =3D imx335_get_pad_format, + .get_fmt =3D v4l2_subdev_get_fmt, .set_fmt =3D imx335_set_pad_format, }; =20 @@ -1226,9 +1189,6 @@ static int imx335_init_controls(struct imx335 *imx335) if (ret) return ret; =20 - /* Serialize controls with sensor device */ - ctrl_hdlr->lock =3D &imx335->mutex; - /* Initialize exposure and gain */ lpfr =3D mode->vblank + mode->height; imx335->exp_ctrl =3D v4l2_ctrl_new_std(ctrl_hdlr, @@ -1348,12 +1308,10 @@ static int imx335_probe(struct i2c_client *client) return ret; } =20 - mutex_init(&imx335->mutex); - ret =3D imx335_power_on(imx335->dev); if (ret) { dev_err(imx335->dev, "failed to power-on the sensor\n"); - goto error_mutex_destroy; + return ret; } =20 /* Check module identity */ @@ -1386,11 +1344,18 @@ static int imx335_probe(struct i2c_client *client) goto error_handler_free; } =20 + imx335->sd.state_lock =3D imx335->ctrl_handler.lock; + ret =3D v4l2_subdev_init_finalize(&imx335->sd); + if (ret < 0) { + dev_err(imx335->dev, "subdev init error\n"); + goto error_media_entity; + } + ret =3D v4l2_async_register_subdev_sensor(&imx335->sd); if (ret < 0) { dev_err(imx335->dev, "failed to register async subdev: %d\n", ret); - goto error_media_entity; + goto error_subdev_cleanup; } =20 pm_runtime_set_active(imx335->dev); @@ -1399,14 +1364,14 @@ static int imx335_probe(struct i2c_client *client) =20 return 0; =20 +error_subdev_cleanup: + v4l2_subdev_cleanup(&imx335->sd); error_media_entity: media_entity_cleanup(&imx335->sd.entity); error_handler_free: v4l2_ctrl_handler_free(imx335->sd.ctrl_handler); error_power_off: imx335_power_off(imx335->dev); -error_mutex_destroy: - mutex_destroy(&imx335->mutex); =20 return ret; } @@ -1420,9 +1385,9 @@ static int imx335_probe(struct i2c_client *client) static void imx335_remove(struct i2c_client *client) { struct v4l2_subdev *sd =3D i2c_get_clientdata(client); - struct imx335 *imx335 =3D to_imx335(sd); =20 v4l2_async_unregister_subdev(sd); + v4l2_subdev_cleanup(sd); media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(sd->ctrl_handler); =20 @@ -1430,8 +1395,6 @@ static void imx335_remove(struct i2c_client *client) if (!pm_runtime_status_suspended(&client->dev)) imx335_power_off(&client->dev); pm_runtime_set_suspended(&client->dev); - - mutex_destroy(&imx335->mutex); } =20 static const struct dev_pm_ops imx335_pm_ops =3D { --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C33CE33C52D; Thu, 30 Oct 2025 08:43:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813834; cv=none; b=Zilk0RvSxkXMgCcZdZnrmWdspx0WSGGzuCZ7gAXDbEMYGdYzR7YkzGAlUHnhXzost06lMpK6LNsV49+XDZwNn4Pb3yTmLpJVpyTXZnARcpfFGeSF1EdSErFwlkWk8DxiSkrgrLAxLyi/emWhz17zRJCIdDdwseritPVEbH1Fzn8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813834; c=relaxed/simple; bh=3Vv1YDwr/jKDyvGCxGOGviKwGZZ2+Bdi96gm030dTIc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Uxtd/GNLklP4irItGLsJ0M2zl/Ofp0eJ1z6J1kr000+MI1EIghqOTriaCjUr8qBNknohgjIEIMjVOJ9wnGRl2HOYB2N7GU27pDO1M85VvL2y0V26B5b870/xp1WHFnNV63o8+N2G/qVIxjct3SUlMB6TvDUJ0R6mwfY1bEbIQDA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=ksQmqwdk; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ksQmqwdk" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 46E011A8F; Thu, 30 Oct 2025 09:42:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813721; bh=3Vv1YDwr/jKDyvGCxGOGviKwGZZ2+Bdi96gm030dTIc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ksQmqwdk+HM/pjzaTlO2jRXNGSI26IabsSGko6/qTepgU5KQa74O8oQ+y2hwMXLw1 ub5msOEd3uBmirDtgPQAahkI940wlvOpBvctrB/rEFivN1r+HTR9fBYmSyizuOrx8j ooGzGToNsYDBw6ughjAs4W9tx5CpMRfX3URumkg4= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 7/8] media: imx335: Support 2x2 binning Date: Thu, 30 Oct 2025 14:13:00 +0530 Message-ID: <20251030-imx335_binning-v4-7-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Introduce 2x2 binning mode (1312x972@60fps). Since there are multiple modes now, use v4l2_find_nearest_size() to select the appropriate mode in .set_fmt(). For 2x2 binning the minimum shutter value supported is 17 instead of 9. This effects the maximum allowed exposure time, and if not enforced then the sensor produces very dark frames when the minimum shutter limit is violated. Lastly, update the crop size reported to the userspace. When trying 2x2 binning with the datasheet suggested pixel array size (i.e. 2592 / 2 =3D> 1296), on some platforms (Raspberry Pi 5) artefacts are introduced on the right edge of the output image. Instead, using a higher width of 1312 works fine on all platforms. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 275 +++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--= ----------------------------- 1 file changed, 217 insertions(+), 58 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 00e65da5f9ae127f6d61a0fe68691c9f49c26d15..7e6e9950e60ae887db3a1f70e38= fa7f9adfee1c5 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -35,6 +35,7 @@ =20 /* Lines per frame */ #define IMX335_REG_VMAX CCI_REG24_LE(0x3030) +#define IMX335_REG_HMAX CCI_REG16_LE(0x3034) =20 #define IMX335_REG_OPB_SIZE_V CCI_REG8(0x304c) #define IMX335_REG_ADBIT CCI_REG8(0x3050) @@ -42,10 +43,13 @@ =20 #define IMX335_REG_SHUTTER CCI_REG24_LE(0x3058) #define IMX335_EXPOSURE_MIN 1 -#define IMX335_EXPOSURE_OFFSET 9 +#define IMX335_SHUTTER_MIN 9 +#define IMX335_SHUTTER_MIN_BINNED 17 #define IMX335_EXPOSURE_STEP 1 #define IMX335_EXPOSURE_DEFAULT 0x0648 =20 +#define IMX335_REG_AREA2_WIDTH_1 CCI_REG16_LE(0x3072) + #define IMX335_REG_AREA3_ST_ADR_1 CCI_REG16_LE(0x3074) #define IMX335_REG_AREA3_WIDTH_1 CCI_REG16_LE(0x3076) =20 @@ -133,12 +137,11 @@ static const struct v4l2_rect imx335_native_area =3D { =20 static const struct v4l2_rect imx335_active_area =3D { .top =3D 50, - .left =3D 52, - .width =3D 2592, + .left =3D 36, + .width =3D 2624, .height =3D 1944, }; =20 - /** * struct imx335_reg_list - imx335 sensor register list * @num_of_regs: Number of registers in the list @@ -155,8 +158,14 @@ static const char * const imx335_supply_name[] =3D { "dvdd", /* Digital Core (1.2V) supply */ }; =20 +enum imx335_scan_mode { + IMX335_ALL_PIXEL, + IMX335_2_2_BINNING, +}; + /** * struct imx335_mode - imx335 sensor mode structure + * @scan_mode: Configuration scan mode (All pixel / 2x2Binning) * @width: Frame width * @height: Frame height * @code: Format code @@ -170,6 +179,7 @@ static const char * const imx335_supply_name[] =3D { * @vflip_inverted: Register list vflip (inverted readout) */ struct imx335_mode { + enum imx335_scan_mode scan_mode; u32 width; u32 height; u32 code; @@ -271,12 +281,33 @@ static const struct cci_reg_sequence mode_2592x1944_r= egs[] =3D { { IMX335_REG_MODE_SELECT, IMX335_MODE_STANDBY }, { IMX335_REG_MASTER_MODE, 0x00 }, { IMX335_REG_WINMODE, 0x04 }, + { IMX335_REG_HMAX, 550 }, { IMX335_REG_HTRIMMING_START, 48 }, { IMX335_REG_HNUM, 2592 }, { IMX335_REG_Y_OUT_SIZE, 1944 }, + { IMX335_REG_AREA2_WIDTH_1, 40 }, { IMX335_REG_AREA3_WIDTH_1, 3928 }, { IMX335_REG_OPB_SIZE_V, 0 }, { IMX335_REG_XVS_XHS_DRV, 0x00 }, +}; + +static const struct cci_reg_sequence mode_1312x972_regs[] =3D { + { IMX335_REG_MODE_SELECT, IMX335_MODE_STANDBY }, + { IMX335_REG_MASTER_MODE, 0x00 }, + { IMX335_REG_WINMODE, 0x01 }, + { IMX335_REG_HMAX, 275 }, + { IMX335_REG_HTRIMMING_START, 48 }, + { IMX335_REG_HNUM, 2600 }, + { IMX335_REG_Y_OUT_SIZE, 972 }, + { IMX335_REG_AREA2_WIDTH_1, 48 }, + { IMX335_REG_AREA3_WIDTH_1, 3936 }, + { IMX335_REG_OPB_SIZE_V, 0 }, + { IMX335_REG_XVS_XHS_DRV, 0x00 }, + { CCI_REG8(0x3300), 1 }, /* TCYCLE */ + { CCI_REG8(0x3199), 0x30 }, /* HADD/VADD */ +}; + +static const struct cci_reg_sequence imx335_common_regs[] =3D { { CCI_REG8(0x3288), 0x21 }, { CCI_REG8(0x328a), 0x02 }, { CCI_REG8(0x3414), 0x05 }, @@ -367,16 +398,72 @@ static const struct cci_reg_sequence mode_2592x1944_v= flip_inverted[] =3D { { CCI_REG16_LE(0x3116), 0x002 }, }; =20 -static const struct cci_reg_sequence raw10_framefmt_regs[] =3D { - { IMX335_REG_ADBIT, 0x00 }, - { IMX335_REG_MDBIT, 0x00 }, - { IMX335_REG_ADBIT1, 0x1ff }, +static const struct cci_reg_sequence mode_1312x972_vflip_normal[] =3D { + { IMX335_REG_AREA3_ST_ADR_1, 176 }, + + /* Undocumented */ + { CCI_REG8(0x3078), 0x04 }, + { CCI_REG8(0x3079), 0xfd }, + { CCI_REG8(0x307a), 0x04 }, + { CCI_REG8(0x307b), 0xfe }, + { CCI_REG8(0x307c), 0x04 }, + { CCI_REG8(0x307d), 0xfb }, + { CCI_REG8(0x307e), 0x04 }, + { CCI_REG8(0x307f), 0x02 }, + { CCI_REG8(0x3080), 0x04 }, + { CCI_REG8(0x3081), 0xfd }, + { CCI_REG8(0x3082), 0x04 }, + { CCI_REG8(0x3083), 0xfe }, + { CCI_REG8(0x3084), 0x04 }, + { CCI_REG8(0x3085), 0xfb }, + { CCI_REG8(0x3086), 0x04 }, + { CCI_REG8(0x3087), 0x02 }, + { CCI_REG8(0x30a4), 0x77 }, + { CCI_REG8(0x30a8), 0x20 }, + { CCI_REG8(0x30a9), 0x00 }, + { CCI_REG8(0x30ac), 0x08 }, + { CCI_REG8(0x30ad), 0x08 }, + { CCI_REG8(0x30b0), 0x20 }, + { CCI_REG8(0x30b1), 0x00 }, + { CCI_REG8(0x30b4), 0x10 }, + { CCI_REG8(0x30b5), 0x10 }, + { CCI_REG16_LE(0x30b6), 0x00 }, + { CCI_REG16_LE(0x3112), 0x10 }, + { CCI_REG16_LE(0x3116), 0x10 }, }; =20 -static const struct cci_reg_sequence raw12_framefmt_regs[] =3D { - { IMX335_REG_ADBIT, 0x01 }, - { IMX335_REG_MDBIT, 0x01 }, - { IMX335_REG_ADBIT1, 0x47 }, +static const struct cci_reg_sequence mode_1312x972_vflip_inverted[] =3D { + { IMX335_REG_AREA3_ST_ADR_1, 4112 }, + + /* Undocumented */ + { CCI_REG8(0x3078), 0x04 }, + { CCI_REG8(0x3079), 0xfd }, + { CCI_REG8(0x307a), 0x04 }, + { CCI_REG8(0x307b), 0xfe }, + { CCI_REG8(0x307c), 0x04 }, + { CCI_REG8(0x307d), 0xfb }, + { CCI_REG8(0x307e), 0x04 }, + { CCI_REG8(0x307f), 0x02 }, + { CCI_REG8(0x3080), 0xfc }, + { CCI_REG8(0x3081), 0x05 }, + { CCI_REG8(0x3082), 0xfc }, + { CCI_REG8(0x3083), 0x02 }, + { CCI_REG8(0x3084), 0xfc }, + { CCI_REG8(0x3085), 0x03 }, + { CCI_REG8(0x3086), 0xfc }, + { CCI_REG8(0x3087), 0xfe }, + { CCI_REG8(0x30a4), 0x77 }, + { CCI_REG8(0x30a8), 0x20 }, + { CCI_REG8(0x30a9), 0x00 }, + { CCI_REG8(0x30ac), 0x08 }, + { CCI_REG8(0x30ad), 0x78 }, + { CCI_REG8(0x30b0), 0x20 }, + { CCI_REG8(0x30b1), 0x00 }, + { CCI_REG8(0x30b4), 0x10 }, + { CCI_REG8(0x30b5), 0x70 }, + { CCI_REG16_LE(0x30b6), 0x01f2 }, + { CCI_REG16_LE(0x3112), 0x10 }, + { CCI_REG16_LE(0x3116), 0x02 }, }; =20 static const struct cci_reg_sequence mipi_data_rate_1188Mbps[] =3D { @@ -441,25 +528,49 @@ static const u32 imx335_mbus_codes[] =3D { }; =20 /* Supported sensor mode configurations */ -static const struct imx335_mode supported_mode =3D { - .width =3D 2592, - .height =3D 1944, - .hblank =3D 342, - .vblank =3D 2556, - .vblank_min =3D 2556, - .vblank_max =3D 133060, - .pclk =3D 396000000, - .reg_list =3D { - .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_regs), - .regs =3D mode_2592x1944_regs, - }, - .vflip_normal =3D { - .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_normal), - .regs =3D mode_2592x1944_vflip_normal, - }, - .vflip_inverted =3D { - .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_inverted), - .regs =3D mode_2592x1944_vflip_inverted, +static const struct imx335_mode supported_modes[] =3D { + { + .scan_mode =3D IMX335_ALL_PIXEL, + .width =3D 2592, + .height =3D 1944, + .hblank =3D 342, + .vblank =3D 2556, + .vblank_min =3D 2556, + .vblank_max =3D 133060, + .pclk =3D 396000000, + .reg_list =3D { + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_regs), + .regs =3D mode_2592x1944_regs, + }, + .vflip_normal =3D { + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_normal), + .regs =3D mode_2592x1944_vflip_normal, + }, + .vflip_inverted =3D { + .num_of_regs =3D ARRAY_SIZE(mode_2592x1944_vflip_inverted), + .regs =3D mode_2592x1944_vflip_inverted, + } + }, { + .scan_mode =3D IMX335_2_2_BINNING, + .width =3D 1312, + .height =3D 972, + .hblank =3D 155, + .vblank =3D 3528, + .vblank_min =3D 3528, + .vblank_max =3D 133060, + .pclk =3D 396000000, + .reg_list =3D { + .num_of_regs =3D ARRAY_SIZE(mode_1312x972_regs), + .regs =3D mode_1312x972_regs, + }, + .vflip_normal =3D { + .num_of_regs =3D ARRAY_SIZE(mode_1312x972_vflip_normal), + .regs =3D mode_1312x972_vflip_normal, + }, + .vflip_inverted =3D { + .num_of_regs =3D ARRAY_SIZE(mode_1312x972_vflip_inverted), + .regs =3D mode_1312x972_vflip_inverted, + }, }, }; =20 @@ -609,18 +720,22 @@ static int imx335_set_ctrl(struct v4l2_ctrl *ctrl) =20 /* Propagate change of current control to all related controls */ if (ctrl->id =3D=3D V4L2_CID_VBLANK) { + u32 shutter_min =3D IMX335_SHUTTER_MIN; + u32 lpfr; + imx335->vblank =3D imx335->vblank_ctrl->val; + lpfr =3D imx335->vblank + imx335->cur_mode->height; =20 dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u\n", - imx335->vblank, - imx335->vblank + imx335->cur_mode->height); + imx335->vblank, lpfr); + + if (imx335->cur_mode->scan_mode =3D=3D IMX335_2_2_BINNING) + shutter_min =3D IMX335_SHUTTER_MIN_BINNED; =20 ret =3D __v4l2_ctrl_modify_range(imx335->exp_ctrl, IMX335_EXPOSURE_MIN, - imx335->vblank + - imx335->cur_mode->height - - IMX335_EXPOSURE_OFFSET, - 1, IMX335_EXPOSURE_DEFAULT); + lpfr - shutter_min, 1, + IMX335_EXPOSURE_DEFAULT); if (ret) return ret; } @@ -720,17 +835,16 @@ static int imx335_enum_frame_size(struct v4l2_subdev = *sd, struct imx335 *imx335 =3D to_imx335(sd); u32 code; =20 - /* Only a single supported_mode available. */ - if (fsize->index > 0) + if (fsize->index >=3D ARRAY_SIZE(supported_modes)) return -EINVAL; =20 code =3D imx335_get_format_code(imx335, fsize->code); if (fsize->code !=3D code) return -EINVAL; =20 - fsize->min_width =3D supported_mode.width; + fsize->min_width =3D supported_modes[fsize->index].width; fsize->max_width =3D fsize->min_width; - fsize->min_height =3D supported_mode.height; + fsize->min_height =3D supported_modes[fsize->index].height; fsize->max_height =3D fsize->min_height; =20 return 0; @@ -772,9 +886,13 @@ static int imx335_set_pad_format(struct v4l2_subdev *s= d, struct imx335 *imx335 =3D to_imx335(sd); struct v4l2_mbus_framefmt *format; const struct imx335_mode *mode; + struct v4l2_rect *crop; int i, ret =3D 0; =20 - mode =3D &supported_mode; + mode =3D v4l2_find_nearest_size(supported_modes, + ARRAY_SIZE(supported_modes), + width, height, + fmt->format.width, fmt->format.height); =20 for (i =3D 0; i < ARRAY_SIZE(imx335_mbus_codes); i++) { if (imx335_mbus_codes[i] =3D=3D fmt->format.code) @@ -786,6 +904,16 @@ static int imx335_set_pad_format(struct v4l2_subdev *s= d, format =3D v4l2_subdev_state_get_format(sd_state, fmt->pad); *format =3D fmt->format; =20 + crop =3D v4l2_subdev_state_get_crop(sd_state, fmt->pad); + crop->width =3D fmt->format.width; + crop->height =3D fmt->format.height; + if (mode->scan_mode =3D=3D IMX335_2_2_BINNING) { + crop->width *=3D 2; + crop->height *=3D 2; + } + crop->left =3D (imx335_native_area.width - crop->width) / 2; + crop->top =3D (imx335_native_area.height - crop->height) / 2; + if (fmt->which =3D=3D V4L2_SUBDEV_FORMAT_ACTIVE) { ret =3D imx335_update_controls(imx335, mode); if (!ret) @@ -809,7 +937,7 @@ static int imx335_init_state(struct v4l2_subdev *sd, struct v4l2_subdev_format fmt =3D { 0 }; =20 fmt.which =3D sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTI= VE; - imx335_fill_pad_format(imx335, &supported_mode, &fmt); + imx335_fill_pad_format(imx335, &supported_modes[0], &fmt); =20 __v4l2_ctrl_modify_range(imx335->link_freq_ctrl, 0, __fls(imx335->link_freq_bitmap), @@ -832,11 +960,15 @@ static int imx335_get_selection(struct v4l2_subdev *s= d, struct v4l2_subdev_selection *sel) { switch (sel->target) { + case V4L2_SEL_TGT_CROP: + sel->r =3D *v4l2_subdev_state_get_crop(sd_state, 0); + + return 0; + case V4L2_SEL_TGT_NATIVE_SIZE: sel->r =3D imx335_native_area; return 0; =20 - case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_CROP_DEFAULT: case V4L2_SEL_TGT_CROP_BOUNDS: sel->r =3D imx335_active_area; @@ -848,19 +980,35 @@ static int imx335_get_selection(struct v4l2_subdev *s= d, =20 static int imx335_set_framefmt(struct imx335 *imx335) { - switch (imx335->cur_mbus_code) { - case MEDIA_BUS_FMT_SRGGB10_1X10: - return cci_multi_reg_write(imx335->cci, raw10_framefmt_regs, - ARRAY_SIZE(raw10_framefmt_regs), - NULL); - - case MEDIA_BUS_FMT_SRGGB12_1X12: - return cci_multi_reg_write(imx335->cci, raw12_framefmt_regs, - ARRAY_SIZE(raw12_framefmt_regs), - NULL); + /* + * In the all-pixel scan mode the AD conversion shall match the output + * bit width requested. + * + * However, when 2/2 binning is enabled, the AD conversion is always + * 10-bit, so we ensure ADBIT is clear and ADBIT1 is assigned 0x1ff. + * That's as much as the documentation gives us... + */ + int ret =3D 0; + u8 bpp =3D imx335->cur_mbus_code =3D=3D MEDIA_BUS_FMT_SRGGB10_1X10 ? 10 := 12; + u8 ad_conv =3D bpp; + + /* Start with the output mode */ + cci_write(imx335->cci, IMX335_REG_MDBIT, bpp =3D=3D 12, &ret); + + /* Enforce 10 bit AD on binning modes */ + if (imx335->cur_mode->scan_mode =3D=3D IMX335_2_2_BINNING) + ad_conv =3D 10; + + /* AD Conversion configuration */ + if (ad_conv =3D=3D 10) { + cci_write(imx335->cci, IMX335_REG_ADBIT, 0x00, &ret); + cci_write(imx335->cci, IMX335_REG_ADBIT1, 0x1ff, &ret); + } else { /* 12 bit AD Conversion */ + cci_write(imx335->cci, IMX335_REG_ADBIT, 0x01, &ret); + cci_write(imx335->cci, IMX335_REG_ADBIT1, 0x47, &ret); } =20 - return -EINVAL; + return ret; } =20 /** @@ -896,6 +1044,14 @@ static int imx335_start_streaming(struct imx335 *imx3= 35) goto err_rpm_put; } =20 + /* Write sensor common registers */ + ret =3D cci_multi_reg_write(imx335->cci, imx335_common_regs, + ARRAY_SIZE(imx335_common_regs), NULL); + if (ret) { + dev_err(imx335->dev, "fail to write initial registers\n"); + goto err_rpm_put; + } + ret =3D imx335_set_framefmt(imx335); if (ret) { dev_err(imx335->dev, "%s failed to set frame format: %d\n", @@ -1177,7 +1333,7 @@ static int imx335_init_controls(struct imx335 *imx335) struct v4l2_ctrl_handler *ctrl_hdlr =3D &imx335->ctrl_handler; const struct imx335_mode *mode =3D imx335->cur_mode; struct v4l2_fwnode_device_properties props; - u32 lpfr; + u32 lpfr, shutter_min; int ret; =20 ret =3D v4l2_fwnode_device_parse(imx335->dev, &props); @@ -1191,11 +1347,14 @@ static int imx335_init_controls(struct imx335 *imx3= 35) =20 /* Initialize exposure and gain */ lpfr =3D mode->vblank + mode->height; + shutter_min =3D IMX335_SHUTTER_MIN; + if (mode->scan_mode =3D=3D IMX335_2_2_BINNING) + shutter_min =3D IMX335_SHUTTER_MIN_BINNED; imx335->exp_ctrl =3D v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_EXPOSURE, IMX335_EXPOSURE_MIN, - lpfr - IMX335_EXPOSURE_OFFSET, + lpfr - shutter_min, IMX335_EXPOSURE_STEP, IMX335_EXPOSURE_DEFAULT); =20 @@ -1322,7 +1481,7 @@ static int imx335_probe(struct i2c_client *client) } =20 /* Set default mode to max resolution */ - imx335->cur_mode =3D &supported_mode; + imx335->cur_mode =3D &supported_modes[0]; imx335->cur_mbus_code =3D imx335_mbus_codes[0]; imx335->vblank =3D imx335->cur_mode->vblank; =20 --=20 2.51.0 From nobody Tue Dec 16 16:41:23 2025 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 61F5A21770B; Thu, 30 Oct 2025 08:43:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813840; cv=none; b=DwH6mtboTXV78kRZ3MqV1Jtnsnnqdlsq1JFZnpd+Rs7ndsqG+/cSvkEYsTCtH1ql1VeZFL6a5yCNDuBQeozKdKVDePJiSojPNFgVd7lvfbeatfRt5peh/DUeNNDB9vAlDflzMIUk6XG37nQi4BDAz6Oaqdodxef4TwQWGEuWx84= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761813840; c=relaxed/simple; bh=9In6pxPNUoqOT4j2XRIApFPGaJyS5HYdYnHdhN6GgAU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DxYHDwww/dujChles/S0/EY30A607LSM77YNmKOkVAXY0nvsJ9e1/5SJyyD+OcuCF3Ljanqh4AhHSgwTMeKaCFoOinDBtV5CplpJwgUL2cRD1JTRpsn2upbQKG51zsQVjmVSa0DXhbsNHfiop/oWLbdlusA3d5PNKyEtM+R2Ba0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=cW/RNcMW; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cW/RNcMW" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:314e:ee86:ae6e:30:9d13]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C8BE61A8F; Thu, 30 Oct 2025 09:42:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761813727; bh=9In6pxPNUoqOT4j2XRIApFPGaJyS5HYdYnHdhN6GgAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cW/RNcMWIn/zX0wv9XMxBNejlyKGqovK6lywqCYWy36Sb7rNzfmV7NmSZj7ETqnTN UTsgcG8bnnkhl+KaTLwtRORUSoyHCCU6/1sbO4cVNfUAGLKXPOdCMtRJZBZJwVLcP8 HJmwVupGOaUjjUC09Y2al8Zx627n9P1Dp1lYylzA= From: Jai Luthra To: Kieran Bingham , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Umang Jain , Jai Luthra Subject: [PATCH v4 8/8] media: imx335: Switch to {enable,disable}_streams Date: Thu, 30 Oct 2025 14:13:01 +0530 Message-ID: <20251030-imx335_binning-v4-8-534f82415aa7@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> References: <20251030-imx335_binning-v4-0-534f82415aa7@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Switch from s_stream to enable_streams and disable_streams callbacks. Reviewed-by: Kieran Bingham Signed-off-by: Jai Luthra --- drivers/media/i2c/imx335.c | 53 ++++++++++++++++++++++++------------------= ----------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 7e6e9950e60ae887db3a1f70e38fa7f9adfee1c5..e94d9f72027c8a32b25836239bc= 8d58c55c7ee7d 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -1012,13 +1012,19 @@ static int imx335_set_framefmt(struct imx335 *imx33= 5) } =20 /** - * imx335_start_streaming() - Start sensor stream - * @imx335: pointer to imx335 device + * imx335_enable_streams() - Enable sensor streams + * @sd: V4L2 subdevice + * @state: V4L2 subdevice state + * @pad: The pad to enable + * @streams_mask: Bitmask of streams to enable * * Return: 0 if successful, error code otherwise. */ -static int imx335_start_streaming(struct imx335 *imx335) +static int imx335_enable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) { + struct imx335 *imx335 =3D to_imx335(sd); const struct imx335_reg_list *reg_list; int ret; =20 @@ -1092,37 +1098,24 @@ static int imx335_start_streaming(struct imx335 *im= x335) } =20 /** - * imx335_stop_streaming() - Stop sensor stream - * @imx335: pointer to imx335 device - */ -static void imx335_stop_streaming(struct imx335 *imx335) -{ - cci_write(imx335->cci, IMX335_REG_MODE_SELECT, - IMX335_MODE_STANDBY, NULL); - pm_runtime_put(imx335->dev); -} - -/** - * imx335_set_stream() - Enable sensor streaming - * @sd: pointer to imx335 subdevice - * @enable: set to enable sensor streaming + * imx335_disable_streams() - Disable sensor streams + * @sd: V4L2 subdevice + * @state: V4L2 subdevice state + * @pad: The pad to disable + * @streams_mask: Bitmask of streams to disable * * Return: 0 if successful, error code otherwise. */ -static int imx335_set_stream(struct v4l2_subdev *sd, int enable) +static int imx335_disable_streams(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, u32 pad, + u64 streams_mask) { struct imx335 *imx335 =3D to_imx335(sd); - struct v4l2_subdev_state *state; - int ret =3D 0; - - state =3D v4l2_subdev_lock_and_get_active_state(sd); - - if (enable) - ret =3D imx335_start_streaming(imx335); - else - imx335_stop_streaming(imx335); + int ret; =20 - v4l2_subdev_unlock_state(state); + ret =3D cci_write(imx335->cci, IMX335_REG_MODE_SELECT, + IMX335_MODE_STANDBY, NULL); + pm_runtime_put(imx335->dev); =20 return ret; } @@ -1242,7 +1235,7 @@ static int imx335_parse_hw_config(struct imx335 *imx3= 35) =20 /* V4l2 subdevice ops */ static const struct v4l2_subdev_video_ops imx335_video_ops =3D { - .s_stream =3D imx335_set_stream, + .s_stream =3D v4l2_subdev_s_stream_helper, }; =20 static const struct v4l2_subdev_pad_ops imx335_pad_ops =3D { @@ -1252,6 +1245,8 @@ static const struct v4l2_subdev_pad_ops imx335_pad_op= s =3D { .set_selection =3D imx335_get_selection, .get_fmt =3D v4l2_subdev_get_fmt, .set_fmt =3D imx335_set_pad_format, + .enable_streams =3D imx335_enable_streams, + .disable_streams =3D imx335_disable_streams, }; =20 static const struct v4l2_subdev_ops imx335_subdev_ops =3D { --=20 2.51.0