From patchwork Tue Oct 29 08:57:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 839499 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 C0C02204029; Tue, 29 Oct 2024 08:58:36 +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=1730192318; cv=none; b=tePjgiSt0ZzslpAUd2teGwDS4nfcyzllOyoPkmjf0NMR4WKvIxIRcG8OjfEzXHJz4n7efHiIJP/Igu0RXOZRstchyo9GwBJnGJ2s6ok5NRsz83OeMPHUcGk8ekr0R6UZxvUr5FCGjF+Bml3CW8c1jv4W9f1AnJUXuGfuCAjPEqo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730192318; c=relaxed/simple; bh=b5kMoUY5fEN9QNCesVCHdR6TYNW7ZndQEXVBK7dSQak=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hWF7U9Iz2NKW5T63pW2JtDu6v8Ch6CnSLsEilO8F6BKq4rrBIkQviFl/jdlg33JHtONtM0J+MtvAJpNL+sWuA4PC2zjZFjOKEk5h9OKM2yPATeQipCTsmDG/ZLA3ByKdl0PZCrP4J22m44MG9RnSyQUvBEHUBIsFk9XNZbcT4Y0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (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=DMZHoHvS; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (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="DMZHoHvS" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:883a:9301:2bb5:b494:2d46:ba69]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 92AF74D4; Tue, 29 Oct 2024 09:58:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1730192313; bh=b5kMoUY5fEN9QNCesVCHdR6TYNW7ZndQEXVBK7dSQak=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=DMZHoHvSTy35aAN9FbA+tM/VqthB7dtuElsOYVIjWw1Oaw1iOcWFm1eQrN28MI8r7 1BAL0j+dJlhBL4RdgwRWZjeS2xGNxH3JJbznqAGf7t7FiFKbVNGf8L20YyR3T9dPYd n63KNT4FGGFWtW+9DUYsp9FQWXhwarmVMEFTpfn4= From: Jai Luthra Date: Tue, 29 Oct 2024 14:27:35 +0530 Subject: [PATCH 1/3] media: i2c: imx219: Correct the minimum vblanking value Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241029-imx219_fixes-v1-1-b45dc3658b4e@ideasonboard.com> References: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> In-Reply-To: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jai Luthra , David Plowman X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=887; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=GYqSOn1ss8LemMDmik0yF8hzBMbOBLBFwe7AEg2ce80=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnIKOuJHWdyujo+MgOVJi/D9lfJvO0/VtJxyjO0 S99omv+q7mJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZyCjrgAKCRBD3pH5JJpx RT6dEACnnI3tI2rAwUH48j65f7pkyhCMmK4rGeGo9dmxoOtLmiu+iuQlwMfWCkl/MZtjMmoLGGQ kVP1+wHLEZpM1dpJhAOzpQARh3e9InA5xIYatYYs0ekrp5YzCIbs18BPQiPCSqvZwAlR3+DzzVk AIDR/HlnaspcXYwTwP1yIRI4uHdxMeIjNV/sIt9AEWJVyfI4cL9KdY9WnaEppiDdUcwWSlnknb8 Csmy8pnveKOHMosDuILVDj9MJKZPWQ3ly3bB4C558SejvodZYqzLnTzoaJP8xjoPnHTIK2iPz91 mFwWnl7le5T/92Tl4TWTBVZSw3g7gxFvkxR2DLAAweUvMI0TNYJWvuwYX0pds7A4RawvhQItmea /MMHXLBPHZJUYqGD69XJlYeqj59LwtrXLPUxGp8+EJ//FmXhwP8h0/J7GE7/wWnYsY/CpMnrA/N YjThcMr8jWVy2tm2U2hoHnr0aibWc2/v9b94n35lRj1Y7l4U5kK9mAWvdFXlKlU2dG9a4+cae15 nqnExdf5q0cISDWCTmbP78mnJVxqJuNm1DufNIsOaMVejHoxLveMdIfxbXkh3g/fAm8/Zl6A7op ZY1a0whLR+JSufpUducC7kLuIsKVKYY+zTZZ19LgUzUFk06UQ+JPoz2L9UNPY5s2Ub9RSedt+c2 Q6SR9Ov3h5ko4DA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: David Plowman The datasheet for this sensor documents the minimum vblanking as being 32 lines. It does fix some problems with occasional black lines at the bottom of images (tested on Raspberry Pi). Signed-off-by: David Plowman Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index e78a80b2bb2e455c857390b188c128b28c224778..f98aad74fe584a18e2fe7126f92bf294762a54e3 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -74,7 +74,7 @@ #define IMX219_REG_VTS CCI_REG16(0x0160) #define IMX219_VTS_MAX 0xffff -#define IMX219_VBLANK_MIN 4 +#define IMX219_VBLANK_MIN 32 /* HBLANK control - read only */ #define IMX219_PPL_DEFAULT 3448 From patchwork Tue Oct 29 08:57:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 839999 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 E41D3204030; Tue, 29 Oct 2024 08:58:43 +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=1730192327; cv=none; b=fmzSFXyV1/oHv8dB3gsyQmx9FDIeYDgshZ4RduIum9W8xT0K/vcYShHDGnU4XSlah1SgOoW51t8j65e6F/j2WkgPGfjP7hFi2K9pRHnVb20+yRDywx26MaSjqyJ8mj5VE8qNf76kFCg/gSthXFkq6zI9MmdKuOhMWxNKIaxcQTE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730192327; c=relaxed/simple; bh=0FEs/gIX99kz8JpOvHrvJN2dpFqvML8cWtHwraR2EGw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WtPY4s31iPEQZFkEXI8vcVv9xWZ1uqxAvjnN/OgFvnW3MhbWAaxYCeNIfJ0ArM0nLJqq7EFO3SIU+KBvIFfQq1oXpo83NjwIPs7nREaTtocBOeBfpKSoFNdiKhWEXTFbJ9zEdd88CYTLGBn/t4d5Vr6dFsK+h82ADcIRdi0vZbY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (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=VpC+mVIa; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (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="VpC+mVIa" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:883a:9301:2bb5:b494:2d46:ba69]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AACE54D4; Tue, 29 Oct 2024 09:58:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1730192320; bh=0FEs/gIX99kz8JpOvHrvJN2dpFqvML8cWtHwraR2EGw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VpC+mVIauVVw3jIpyhGbdOWzorXWu3/ZYaRBHzY3L6s1zT0ACx+kVRxYJ/UaGTBCC ZXKZVNa38ghCaHfECVlRbu0JB5uN/ZLTqzml1Hxvdu1dsNf86oCp5M2YDPX7qSdpuD J1eA0SRtPwJrOJF5BztqdNTd1pNNEYH6F8cls1KE= From: Jai Luthra Date: Tue, 29 Oct 2024 14:27:36 +0530 Subject: [PATCH 2/3] media: i2c: imx219: make HBLANK r/w to allow longer exposures Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241029-imx219_fixes-v1-2-b45dc3658b4e@ideasonboard.com> References: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> In-Reply-To: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jai Luthra X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3702; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=e6R2yb1OtTps+G3Y/rqGJ9x5BhQfEck/djqyB7t/WzM=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnIKOvZ0xjExV4inWaTSq4DYpGu/DOF5d39Aw85 nP/dfujeviJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZyCjrwAKCRBD3pH5JJpx ReqzD/9qS5UKt0S/yuW0WXdT/x/1BDpKKJfXmdav3wjn0+N4zkouHNs7y2RcLpyUSzJmi0vGmCD 2QNLM3MbpqcDOM/y2xN6jLOqciZr9Pkyb0SGaAHQYTU8LfC6B4FPBKE622/5SsgtQVMRT1GOG80 78wzxbMdjWM7HmGsgzmOabVXuom1sruHmzaE6Pux5NJXQKNaXPZg3OlmIUR62XJM3H0aw78Hu+G KvdBJK3AFD/ncaQ3JlU6W9H897KJWZC0gzsEnb17oitrM+GsVTFInEfgyonKX/I80gccMC1lw2F 1XwRJXBJoeCz2qkNAGTGc5IPYCSIShnKCOa7W7ZPJgkj4QznIce12NGXLOzqwyAgvabig+lair8 kyv0zGO/Ml8xTXtAu5BJeuH6gZfEP470h8a7UW23nf5l3RZ8vI/laVSCnzlAqVX+Lz6uC7I8wD5 FC08J7G19YlPYXZHjfca4ELtTuui3WkqF7dfLSs+8ifx9kqVss6N05/jT4ig4C07cLzMmWKpEV/ aSGxMFLkz0HyrFhtfbMPSa0lb1g325F4s917IrWI+ChQ2KffVdv9YIOsX9UMnkGh0kQGe+pm0Nu n5gYxRYhs/LH7yatVo+CB1fhLwSfCgzzBuWUX3BEBx/jA4Fybpdtds9O5rbcHfY4GqBQVQb3juE ArXPqSJrLGzEIig== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 From: Dave Stevenson The HBLANK control was read-only, and always configured such that the sensor HTS register was 3448. This limited the maximum exposure time that could be achieved to around 1.26 secs. Make HBLANK read/write so that the line time can be extended, and thereby allow longer exposures (and slower frame rates). Retain the overall HTS setting when changing modes rather than resetting it to a default. Signed-off-by: Dave Stevenson Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index f98aad74fe584a18e2fe7126f92bf294762a54e3..de9230d4ad81f085640be254db9391ae7ad20773 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -76,8 +76,10 @@ #define IMX219_VBLANK_MIN 32 -/* HBLANK control - read only */ -#define IMX219_PPL_DEFAULT 3448 +/* HBLANK control range */ +#define IMX219_PPL_MIN 3448 +#define IMX219_PPL_MAX 0x7ff0 +#define IMX219_REG_HTS CCI_REG16(0x0162) #define IMX219_REG_LINE_LENGTH_A CCI_REG16(0x0162) #define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164) @@ -422,6 +424,10 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) cci_write(imx219->regmap, IMX219_REG_VTS, format->height + ctrl->val, &ret); break; + case V4L2_CID_HBLANK: + cci_write(imx219->regmap, IMX219_REG_HTS, + format->width + ctrl->val, &ret); + break; case V4L2_CID_TEST_PATTERN_RED: cci_write(imx219->regmap, IMX219_REG_TESTP_RED, ctrl->val, &ret); @@ -496,12 +502,11 @@ static int imx219_init_controls(struct imx219 *imx219) V4L2_CID_VBLANK, IMX219_VBLANK_MIN, IMX219_VTS_MAX - mode->height, 1, mode->vts_def - mode->height); - hblank = IMX219_PPL_DEFAULT - mode->width; + hblank = IMX219_PPL_MIN - mode->width; imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HBLANK, hblank, hblank, + V4L2_CID_HBLANK, hblank, + IMX219_PPL_MIN - mode->width, 1, hblank); - if (imx219->hblank) - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; exposure_max = mode->vts_def - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; @@ -842,6 +847,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + u32 prev_hts = format->width + imx219->hblank->val; int exposure_max; int exposure_def; int hblank; @@ -861,13 +867,18 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, exposure_max, imx219->exposure->step, exposure_def); /* - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank - * depends on mode->width only, and is not changeble in any - * way other than changing the mode. + * Retain PPL setting from previous mode so that the + * line time does not change on a mode change. + * Limits have to be recomputed as the controls define + * the blanking only, so PPL values need to have the + * mode width subtracted. */ - hblank = IMX219_PPL_DEFAULT - mode->width; - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, - hblank); + hblank = prev_hts - mode->width; + __v4l2_ctrl_modify_range(imx219->hblank, + IMX219_PPL_MIN - mode->width, + IMX219_PPL_MAX - mode->width, + 1, IMX219_PPL_MIN - mode->width); + __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); } return 0; From patchwork Tue Oct 29 08:57:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 839498 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 4C1822040B4; Tue, 29 Oct 2024 08:58:50 +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=1730192332; cv=none; b=jFmfE2hAtj6/lNHsQs1EXRJvT52YnneDe5+VdbgmuZ3OXQ3umV35PPxLtZp6SrhBhROrmy0rVlSjvYjHNVNq6afp6wDabpG8nobM8l04zIbvdUv/imL/hjM17qYyX5hv9pTNg1f+xefXMPemm/5ag+EosOs+BIjJ6mlXsxscyIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730192332; c=relaxed/simple; bh=Fx+ZSitJDsRhbmKyNtCyWgmJ9SSe+CJOJv/iwxjeeLs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=snFzHg2NWt7uOcaDyCDWKzTWhvbauzeLZrLGTJkQoKqSrCo+PnQN/7uPb2nxoCVgSL9VQkOYqTLE7u2xmjR2a3w5EWyVRTcKUIV8+wvR+CSRW3D/y2nMgxZ5tEPWtTExHPpAydiSkHeuPR7fYIUzqyvCvNJjpAD4l2EqE5LzghA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (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=uIfGsr1x; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (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="uIfGsr1x" Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:883a:9301:2bb5:b494:2d46:ba69]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 581D94D4; Tue, 29 Oct 2024 09:58:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1730192326; bh=Fx+ZSitJDsRhbmKyNtCyWgmJ9SSe+CJOJv/iwxjeeLs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=uIfGsr1xBV5EPygzaYWPkejHx0MzaZdbvqsUKTnHdz/9SfIy7HhG9TAO8zxErGn3n Nz2znrYg+40uCcg20A/A4lXFJqBXKW4x+Uy4jeWh2A2/5L/PA0k+9Fw2+SZiFLUU0M UvX3KGB+KsqAG9O9fPcWRJrsKrdOmRsCpwGH5q8k= From: Jai Luthra Date: Tue, 29 Oct 2024 14:27:37 +0530 Subject: [PATCH 3/3] media: i2c: imx219: Scale the pixel rate for analog binning Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241029-imx219_fixes-v1-3-b45dc3658b4e@ideasonboard.com> References: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> In-Reply-To: <20241029-imx219_fixes-v1-0-b45dc3658b4e@ideasonboard.com> To: Dave Stevenson , Sakari Ailus , Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Jai Luthra , Naushir Patuck , Vinay Varma X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=9544; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=Fx+ZSitJDsRhbmKyNtCyWgmJ9SSe+CJOJv/iwxjeeLs=; b=owEBbQKS/ZANAwAIAUPekfkkmnFFAcsmYgBnIKOvxiDSE+4uk6EMl1/Qu8IrRbIUZlQ5gdoUK FdJnji8XouJAjMEAAEIAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCZyCjrwAKCRBD3pH5JJpx Rc4gEAC0Pth/HTrLWl3GddonDUmNiN5V6xm4gEZxU5fMIw+jYtCeJfK/JypLwml8hJqOjN/Dxcd un6X+Z6VhMIGPHr9mihw7dHGP49wbh+q0GqlUjU4lMuHzE2rv1UUaUMGMXwGGQiEvirxFJUS7/B AZAudxbNF8NodhVsGsa+XcsFFMvAC4RYJp4B7u/9FXvYEpHy0Hz14p28LH7q7mQYicx4Eai9bwK Pc68rt3TLGGCuM0QxFMcQSr2bSiMWeXGzviR19WlMmeI9iaYh75a82j0sOI+1mCyWM+iiAGceva /MDmfK24a+OkVeAQjVZWw4tbpenPNnGBqgoaziGuyDasymF0SJzruf1RAPmp+sSOBqa8llTORGX XATRYDaa4HhIXFXtGhqFnp6AW8CnhJu/oenHtrS+DeJI7SToVWbBpQj9SH2MKCbMEtS1k75ccVc sgLJ824e4JCBL8tzdgzudI1SsZXahd6eVXbtYgPuWgOSJgUFM6EBy62fr9P8hoWHElQ+7pwlsIC bzeU7n3SCr50y9ooRN9nEaNEaMY1USCs9hKdaSjFwQVUo36a/gJTOF6kTWMYmYs8HZT+00q5TSg JjO2/XN3uNJa2ek3s3kjmrwJEibwSZkb49Nva2Bj2FM91syYiTroVwAl41hj6pl2Euld8d19+Dk yg4hc45lPH47dCA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 When the analog binning mode is used for high framerate operation, the pixel rate is effectively doubled. Account for this when setting up the pixel clock rate, and applying the vblank and exposure controls. The previous logic only used analog binning for 8-bit modes, but normal binning limits the framerate on 10-bit 480p [1]. So with this patch we switch to using special binning (with 2x pixel rate) for all formats of 480p mode and 8-bit 1232p. To do this cleanly, re-introduce the book-keeping for which binning mode is used with which resolution/format. [1]: https://github.com/raspberrypi/linux/issues/5493 Co-developed-by: Naushir Patuck Signed-off-by: Naushir Patuck Co-developed-by: Vinay Varma Signed-off-by: Vinay Varma Signed-off-by: Jai Luthra --- drivers/media/i2c/imx219.c | 149 ++++++++++++++++++++++++++++++++------------- 1 file changed, 106 insertions(+), 43 deletions(-) diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index de9230d4ad81f085640be254db9391ae7ad20773..140d958f80eb57dfb4ecf1796fcdf77081a662d7 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -149,6 +149,18 @@ #define IMX219_PIXEL_ARRAY_WIDTH 3280U #define IMX219_PIXEL_ARRAY_HEIGHT 2464U +enum binning_mode { + BINNING_NONE, + BINNING_X2, + BINNING_ANALOG_X2, +}; + +enum binning_bit_depths { + BINNING_IDX_8_BIT, + BINNING_IDX_10_BIT, + BINNING_IDX_MAX +}; + /* Mode : resolution and related config&values */ struct imx219_mode { /* Frame width */ @@ -158,6 +170,9 @@ struct imx219_mode { /* V-timing */ unsigned int vts_def; + + /* binning mode based on format code */ + enum binning_mode binning[BINNING_IDX_MAX]; }; static const struct cci_reg_sequence imx219_common_regs[] = { @@ -293,24 +308,40 @@ static const struct imx219_mode supported_modes[] = { .width = 3280, .height = 2464, .vts_def = 3526, + .binning = { + [BINNING_IDX_8_BIT] = BINNING_NONE, + [BINNING_IDX_10_BIT] = BINNING_NONE, + }, }, { /* 1080P 30fps cropped */ .width = 1920, .height = 1080, .vts_def = 1763, + .binning = { + [BINNING_IDX_8_BIT] = BINNING_NONE, + [BINNING_IDX_10_BIT] = BINNING_NONE, + }, }, { /* 2x2 binned 30fps mode */ .width = 1640, .height = 1232, .vts_def = 1763, + .binning = { + [BINNING_IDX_8_BIT] = BINNING_ANALOG_X2, + [BINNING_IDX_10_BIT] = BINNING_X2, + }, }, { /* 640x480 30fps mode */ .width = 640, .height = 480, .vts_def = 1763, + .binning = { + [BINNING_IDX_8_BIT] = BINNING_ANALOG_X2, + [BINNING_IDX_10_BIT] = BINNING_ANALOG_X2, + }, }, }; @@ -337,6 +368,9 @@ struct imx219 { /* Two or Four lanes */ u8 lanes; + + /* Binning mode */ + enum binning_mode binning; }; static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd) @@ -362,6 +396,36 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) return imx219_mbus_formats[i]; } +static u32 imx219_get_format_bpp(const struct v4l2_mbus_framefmt *format) +{ + switch (format->code) { + case MEDIA_BUS_FMT_SRGGB8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + return 8; + + case MEDIA_BUS_FMT_SRGGB10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + default: + return 10; + } +} + +static int imx219_get_rate_factor(struct imx219 *imx219) +{ + switch (imx219->binning) { + case BINNING_NONE: + case BINNING_X2: + return 1; + case BINNING_ANALOG_X2: + return 2; + } + return -EINVAL; +} + /* ----------------------------------------------------------------------------- * Controls */ @@ -373,10 +437,12 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); const struct v4l2_mbus_framefmt *format; struct v4l2_subdev_state *state; + int rate_factor; int ret = 0; state = v4l2_subdev_get_locked_active_state(&imx219->sd); format = v4l2_subdev_state_get_format(state, 0); + rate_factor = imx219_get_rate_factor(imx219); if (ctrl->id == V4L2_CID_VBLANK) { int exposure_max, exposure_def; @@ -405,7 +471,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_EXPOSURE: cci_write(imx219->regmap, IMX219_REG_EXPOSURE, - ctrl->val, &ret); + ctrl->val / rate_factor, &ret); break; case V4L2_CID_DIGITAL_GAIN: cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, @@ -422,7 +488,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: cci_write(imx219->regmap, IMX219_REG_VTS, - format->height + ctrl->val, &ret); + (format->height + ctrl->val) / rate_factor, &ret); break; case V4L2_CID_HBLANK: cci_write(imx219->regmap, IMX219_REG_HTS, @@ -463,7 +529,8 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = { static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) { - return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; + return ((imx219->lanes == 2) ? IMX219_PIXEL_RATE : + IMX219_PIXEL_RATE_4LANE) * imx219_get_rate_factor(imx219); } /* Initialize control handlers */ @@ -473,7 +540,7 @@ static int imx219_init_controls(struct imx219 *imx219) const struct imx219_mode *mode = &supported_modes[0]; struct v4l2_ctrl_handler *ctrl_hdlr; struct v4l2_fwnode_device_properties props; - int exposure_max, exposure_def, hblank; + int exposure_max, exposure_def, hblank, pixel_rate; int i, ret; ctrl_hdlr = &imx219->ctrl_handler; @@ -482,11 +549,11 @@ static int imx219_init_controls(struct imx219 *imx219) return ret; /* By default, PIXEL_RATE is read only */ + pixel_rate = imx219_get_pixel_rate(imx219); imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_PIXEL_RATE, - imx219_get_pixel_rate(imx219), - imx219_get_pixel_rate(imx219), 1, - imx219_get_pixel_rate(imx219)); + pixel_rate, pixel_rate, 1, + pixel_rate); imx219->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, @@ -593,29 +660,13 @@ static int imx219_set_framefmt(struct imx219 *imx219, { const struct v4l2_mbus_framefmt *format; const struct v4l2_rect *crop; - unsigned int bpp; - u64 bin_h, bin_v; + u64 binning; + u32 bpp; int ret = 0; format = v4l2_subdev_state_get_format(state, 0); crop = v4l2_subdev_state_get_crop(state, 0); - - switch (format->code) { - case MEDIA_BUS_FMT_SRGGB8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SGBRG8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - bpp = 8; - break; - - case MEDIA_BUS_FMT_SRGGB10_1X10: - case MEDIA_BUS_FMT_SGRBG10_1X10: - case MEDIA_BUS_FMT_SGBRG10_1X10: - case MEDIA_BUS_FMT_SBGGR10_1X10: - default: - bpp = 10; - break; - } + bpp = imx219_get_format_bpp(format); cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); @@ -626,28 +677,20 @@ static int imx219_set_framefmt(struct imx219 *imx219, cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); - switch (crop->width / format->width) { - case 1: - default: - bin_h = IMX219_BINNING_NONE; + switch (imx219->binning) { + case BINNING_NONE: + binning = IMX219_BINNING_NONE; break; - case 2: - bin_h = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; - break; - } - - switch (crop->height / format->height) { - case 1: - default: - bin_v = IMX219_BINNING_NONE; + case BINNING_X2: + binning = IMX219_BINNING_X2; break; - case 2: - bin_v = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; + case BINNING_ANALOG_X2: + binning = IMX219_BINNING_X2_ANALOG; break; } - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, bin_h, &ret); - cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, bin_v, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, binning, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, binning, &ret); cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, format->width, &ret); @@ -851,6 +894,21 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, int exposure_max; int exposure_def; int hblank; + int pixel_rate; + + /* Update binning mode based on format */ + switch (imx219_get_format_bpp(format)) { + case 8: + imx219->binning = mode->binning[BINNING_IDX_8_BIT]; + break; + + case 10: + imx219->binning = mode->binning[BINNING_IDX_10_BIT]; + break; + + default: + imx219->binning = BINNING_NONE; + } /* Update limits and set FPS to default */ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, @@ -879,6 +937,11 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd, IMX219_PPL_MAX - mode->width, 1, IMX219_PPL_MIN - mode->width); __v4l2_ctrl_s_ctrl(imx219->hblank, hblank); + + /* Scale the pixel rate based on the mode specific factor */ + pixel_rate = imx219_get_pixel_rate(imx219); + __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate, + pixel_rate, 1, pixel_rate); } return 0;