From patchwork Thu Feb 10 11:04:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541634 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5A00C433F5 for ; Thu, 10 Feb 2022 11:04:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240477AbiBJLEE (ORCPT ); Thu, 10 Feb 2022 06:04:04 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240099AbiBJLEE (ORCPT ); Thu, 10 Feb 2022 06:04:04 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [IPv6:2001:4b98:dc4:8::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 246CC100B for ; Thu, 10 Feb 2022 03:04:04 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 5437A20000C; Thu, 10 Feb 2022 11:04:00 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 01/23] media: ov5640: Add pixel rate to modes Date: Thu, 10 Feb 2022 12:04:36 +0100 Message-Id: <20220210110458.152494-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add to each mode supported by the sensor the ideal pixel rate, as defined by Table 2.1 in the chip manual. The ideal pixel rate will be used to compute the MIPI CSI-2 clock tree. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Tested-by: Adam Ford #imx8mm-beacon-kit --- drivers/media/i2c/ov5640.c | 44 +++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index db5a19babe67..01f4a075f86e 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -118,6 +118,29 @@ enum ov5640_frame_rate { OV5640_NUM_FRAMERATES, }; +enum ov5640_pixel_rate_id { + OV5640_PIXEL_RATE_168M, + OV5640_PIXEL_RATE_148M, + OV5640_PIXEL_RATE_124M, + OV5640_PIXEL_RATE_96M, + OV5640_PIXEL_RATE_48M, + OV5640_NUM_PIXEL_RATES, +}; + +/* + * The chip manual suggests 24/48/96/192 MHz pixel clocks. + * + * 192MHz exceeds the sysclk limits; use 168MHz as maximum pixel rate for + * full resolution mode @15 FPS. + */ +static const u32 ov5640_pixel_rates[] = { + [OV5640_PIXEL_RATE_168M] = 168000000, + [OV5640_PIXEL_RATE_148M] = 148000000, + [OV5640_PIXEL_RATE_124M] = 124000000, + [OV5640_PIXEL_RATE_96M] = 96000000, + [OV5640_PIXEL_RATE_48M] = 48000000, +}; + enum ov5640_format_mux { OV5640_FMT_MUX_YUV422 = 0, OV5640_FMT_MUX_RGB, @@ -189,6 +212,7 @@ struct reg_value { struct ov5640_mode_info { enum ov5640_mode_id id; enum ov5640_downsize_mode dn_mode; + enum ov5640_pixel_rate_id pixel_rate; u32 hact; u32 htot; u32 vact; @@ -565,7 +589,9 @@ static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = { /* power-on sensor init reg table */ static const struct ov5640_mode_info ov5640_mode_init_data = { - 0, SUBSAMPLING, 640, 1896, 480, 984, + 0, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, + 640, 1896, 480, 984, ov5640_init_setting_30fps_VGA, ARRAY_SIZE(ov5640_init_setting_30fps_VGA), OV5640_30_FPS, @@ -574,51 +600,61 @@ static const struct ov5640_mode_info ov5640_mode_init_data = { static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { {OV5640_MODE_QQVGA_160_120, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, 160, 1896, 120, 984, ov5640_setting_QQVGA_160_120, ARRAY_SIZE(ov5640_setting_QQVGA_160_120), OV5640_30_FPS}, {OV5640_MODE_QCIF_176_144, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, 176, 1896, 144, 984, ov5640_setting_QCIF_176_144, ARRAY_SIZE(ov5640_setting_QCIF_176_144), OV5640_30_FPS}, {OV5640_MODE_QVGA_320_240, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, 320, 1896, 240, 984, ov5640_setting_QVGA_320_240, ARRAY_SIZE(ov5640_setting_QVGA_320_240), OV5640_30_FPS}, {OV5640_MODE_VGA_640_480, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, 640, 1896, 480, 1080, ov5640_setting_VGA_640_480, ARRAY_SIZE(ov5640_setting_VGA_640_480), OV5640_60_FPS}, {OV5640_MODE_NTSC_720_480, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, 720, 1896, 480, 984, ov5640_setting_NTSC_720_480, ARRAY_SIZE(ov5640_setting_NTSC_720_480), OV5640_30_FPS}, {OV5640_MODE_PAL_720_576, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, 720, 1896, 576, 984, ov5640_setting_PAL_720_576, ARRAY_SIZE(ov5640_setting_PAL_720_576), OV5640_30_FPS}, {OV5640_MODE_XGA_1024_768, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, 1024, 1896, 768, 1080, ov5640_setting_XGA_1024_768, ARRAY_SIZE(ov5640_setting_XGA_1024_768), OV5640_30_FPS}, {OV5640_MODE_720P_1280_720, SUBSAMPLING, + OV5640_PIXEL_RATE_124M, 1280, 1892, 720, 740, ov5640_setting_720P_1280_720, ARRAY_SIZE(ov5640_setting_720P_1280_720), OV5640_30_FPS}, {OV5640_MODE_1080P_1920_1080, SCALING, + OV5640_PIXEL_RATE_148M, 1920, 2500, 1080, 1120, ov5640_setting_1080P_1920_1080, ARRAY_SIZE(ov5640_setting_1080P_1920_1080), OV5640_30_FPS}, {OV5640_MODE_QSXGA_2592_1944, SCALING, + OV5640_PIXEL_RATE_168M, 2592, 2844, 1944, 1968, ov5640_setting_QSXGA_2592_1944, ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), @@ -2743,6 +2779,7 @@ static const struct v4l2_ctrl_ops ov5640_ctrl_ops = { static int ov5640_init_controls(struct ov5640_dev *sensor) { + const struct ov5640_mode_info *mode = sensor->current_mode; const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops; struct ov5640_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; @@ -2755,8 +2792,9 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) /* Clock related controls */ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE, - 0, INT_MAX, 1, - ov5640_calc_pixel_rate(sensor)); + ov5640_pixel_rates[OV5640_NUM_PIXEL_RATES - 1], + ov5640_pixel_rates[0], 1, + ov5640_pixel_rates[mode->pixel_rate]); /* Auto/manual white balance */ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, From patchwork Thu Feb 10 11:04:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541988 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 085BCC433EF for ; Thu, 10 Feb 2022 11:04:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240478AbiBJLEG (ORCPT ); Thu, 10 Feb 2022 06:04:06 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39464 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLEF (ORCPT ); Thu, 10 Feb 2022 06:04:05 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [IPv6:2001:4b98:dc4:8::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E613D100B for ; Thu, 10 Feb 2022 03:04:06 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id DAFE920000E; Thu, 10 Feb 2022 11:04:02 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 02/23] media: ov5604: Re-arrange modes definition Date: Thu, 10 Feb 2022 12:04:37 +0100 Message-Id: <20220210110458.152494-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The array of supported modes is close to unreadable. Re-arrange it giving it some room to breath. Cosmetic change only. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 141 +++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 60 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 01f4a075f86e..d8285be2bfa1 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -599,66 +599,87 @@ static const struct ov5640_mode_info ov5640_mode_init_data = { static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { - {OV5640_MODE_QQVGA_160_120, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 160, 1896, 120, 984, - ov5640_setting_QQVGA_160_120, - ARRAY_SIZE(ov5640_setting_QQVGA_160_120), - OV5640_30_FPS}, - {OV5640_MODE_QCIF_176_144, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 176, 1896, 144, 984, - ov5640_setting_QCIF_176_144, - ARRAY_SIZE(ov5640_setting_QCIF_176_144), - OV5640_30_FPS}, - {OV5640_MODE_QVGA_320_240, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 320, 1896, 240, 984, - ov5640_setting_QVGA_320_240, - ARRAY_SIZE(ov5640_setting_QVGA_320_240), - OV5640_30_FPS}, - {OV5640_MODE_VGA_640_480, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 640, 1896, 480, 1080, - ov5640_setting_VGA_640_480, - ARRAY_SIZE(ov5640_setting_VGA_640_480), - OV5640_60_FPS}, - {OV5640_MODE_NTSC_720_480, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 720, 1896, 480, 984, - ov5640_setting_NTSC_720_480, - ARRAY_SIZE(ov5640_setting_NTSC_720_480), - OV5640_30_FPS}, - {OV5640_MODE_PAL_720_576, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 720, 1896, 576, 984, - ov5640_setting_PAL_720_576, - ARRAY_SIZE(ov5640_setting_PAL_720_576), - OV5640_30_FPS}, - {OV5640_MODE_XGA_1024_768, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 1024, 1896, 768, 1080, - ov5640_setting_XGA_1024_768, - ARRAY_SIZE(ov5640_setting_XGA_1024_768), - OV5640_30_FPS}, - {OV5640_MODE_720P_1280_720, SUBSAMPLING, - OV5640_PIXEL_RATE_124M, - 1280, 1892, 720, 740, - ov5640_setting_720P_1280_720, - ARRAY_SIZE(ov5640_setting_720P_1280_720), - OV5640_30_FPS}, - {OV5640_MODE_1080P_1920_1080, SCALING, - OV5640_PIXEL_RATE_148M, - 1920, 2500, 1080, 1120, - ov5640_setting_1080P_1920_1080, - ARRAY_SIZE(ov5640_setting_1080P_1920_1080), - OV5640_30_FPS}, - {OV5640_MODE_QSXGA_2592_1944, SCALING, - OV5640_PIXEL_RATE_168M, - 2592, 2844, 1944, 1968, - ov5640_setting_QSXGA_2592_1944, - ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), - OV5640_15_FPS}, + { + /* 160x120 */ + OV5640_MODE_QQVGA_160_120, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, + 160, 1896, 120, 984, + ov5640_setting_QQVGA_160_120, + ARRAY_SIZE(ov5640_setting_QQVGA_160_120), + OV5640_30_FPS + }, { + /* 176x144 */ + OV5640_MODE_QCIF_176_144, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, + 176, 1896, 144, 984, + ov5640_setting_QCIF_176_144, + ARRAY_SIZE(ov5640_setting_QCIF_176_144), + OV5640_30_FPS + }, { + /* 320x240 */ + OV5640_MODE_QVGA_320_240, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, + 320, 1896, 240, 984, + ov5640_setting_QVGA_320_240, + ARRAY_SIZE(ov5640_setting_QVGA_320_240), + OV5640_30_FPS + }, { + /* 640x480 */ + OV5640_MODE_VGA_640_480, SUBSAMPLING, + OV5640_PIXEL_RATE_48M, + 640, 1896, 480, 1080, + ov5640_setting_VGA_640_480, + ARRAY_SIZE(ov5640_setting_VGA_640_480), + OV5640_60_FPS + }, { + /* 720x480 */ + OV5640_MODE_NTSC_720_480, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, + 720, 1896, 480, 984, + ov5640_setting_NTSC_720_480, + ARRAY_SIZE(ov5640_setting_NTSC_720_480), + OV5640_30_FPS + }, { + /* 720x576 */ + OV5640_MODE_PAL_720_576, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, + 720, 1896, 576, 984, + ov5640_setting_PAL_720_576, + ARRAY_SIZE(ov5640_setting_PAL_720_576), + OV5640_30_FPS + }, { + /* 1024x768 */ + OV5640_MODE_XGA_1024_768, SUBSAMPLING, + OV5640_PIXEL_RATE_96M, + 1024, 1896, 768, 1080, + ov5640_setting_XGA_1024_768, + ARRAY_SIZE(ov5640_setting_XGA_1024_768), + OV5640_30_FPS + }, { + /* 1280x720 */ + OV5640_MODE_720P_1280_720, SUBSAMPLING, + OV5640_PIXEL_RATE_124M, + 1280, 1892, 720, 740, + ov5640_setting_720P_1280_720, + ARRAY_SIZE(ov5640_setting_720P_1280_720), + OV5640_30_FPS + }, { + /* 1920x1080 */ + OV5640_MODE_1080P_1920_1080, SCALING, + OV5640_PIXEL_RATE_148M, + 1920, 2500, 1080, 1120, + ov5640_setting_1080P_1920_1080, + ARRAY_SIZE(ov5640_setting_1080P_1920_1080), + OV5640_30_FPS + }, { + /* 2592x1944 */ + OV5640_MODE_QSXGA_2592_1944, SCALING, + OV5640_PIXEL_RATE_168M, + 2592, 2844, 1944, 1968, + ov5640_setting_QSXGA_2592_1944, + ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), + OV5640_15_FPS + }, }; static int ov5640_init_slave_id(struct ov5640_dev *sensor) From patchwork Thu Feb 10 11:04:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541633 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EBDBCC433F5 for ; Thu, 10 Feb 2022 11:04:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240481AbiBJLEI (ORCPT ); Thu, 10 Feb 2022 06:04:08 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLEH (ORCPT ); Thu, 10 Feb 2022 06:04:07 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 581C9100B for ; Thu, 10 Feb 2022 03:04:09 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id ADA26200004; Thu, 10 Feb 2022 11:04:05 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 03/23] media: ov5640: Add ov5640_is_csi2() function Date: Thu, 10 Feb 2022 12:04:38 +0100 Message-Id: <20220210110458.152494-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Checking if the sensor is used in DVP or MIPI CSI-2 mode is a repeated pattern which is about to be repeated more often. Provide an inline function to shortcut that. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index d8285be2bfa1..ce3d38eadb86 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -294,6 +294,11 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) ctrls.handler)->sd; } +static inline bool ov5640_is_csi2(struct ov5640_dev *sensor) +{ + return sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY; +} + /* * FIXME: all of these register tables are likely filled with * entries that set the register to their power-on default values, @@ -1208,7 +1213,7 @@ static int ov5640_load_regs(struct ov5640_dev *sensor, /* remain in power down mode for DVP */ if (regs->reg_addr == OV5640_REG_SYS_CTRL0 && val == OV5640_REG_SYS_CTRL0_SW_PWUP && - sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) + !ov5640_is_csi2(sensor)) continue; if (mask) @@ -1843,7 +1848,7 @@ static int ov5640_set_mode(struct ov5640_dev *sensor) * the same rate than YUV, so we can just use 16 bpp all the time. */ rate = ov5640_calc_pixel_rate(sensor) * 16; - if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) { + if (ov5640_is_csi2(sensor)) { rate = rate / sensor->ep.bus.mipi_csi2.num_data_lanes; ret = ov5640_set_mipi_pclk(sensor, rate); } else { @@ -3020,7 +3025,7 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable) sensor->pending_fmt_change = false; } - if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) + if (ov5640_is_csi2(sensor)) ret = ov5640_set_stream_mipi(sensor, enable); else ret = ov5640_set_stream_dvp(sensor, enable); From patchwork Thu Feb 10 11:04:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541987 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7310DC433F5 for ; Thu, 10 Feb 2022 11:04:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240490AbiBJLEO (ORCPT ); Thu, 10 Feb 2022 06:04:14 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLEK (ORCPT ); Thu, 10 Feb 2022 06:04:10 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [IPv6:2001:4b98:dc4:8::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13439100B for ; Thu, 10 Feb 2022 03:04:11 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 4C130200005; Thu, 10 Feb 2022 11:04:08 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 04/23] media: ov5640: Associate bpp with formats Date: Thu, 10 Feb 2022 12:04:39 +0100 Message-Id: <20220210110458.152494-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Associate the bit depth to each format supported by the sensor. The bpp will be used to calculate the line length. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 73 ++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index ce3d38eadb86..71404d064045 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -150,24 +150,69 @@ enum ov5640_format_mux { OV5640_FMT_MUX_RAW_CIP, }; -struct ov5640_pixfmt { +static const struct ov5640_pixfmt { u32 code; u32 colorspace; + u8 bpp; +} ov5640_formats[] = { + { + .code = MEDIA_BUS_FMT_JPEG_1X8, + .colorspace = V4L2_COLORSPACE_JPEG, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_YUYV8_1X16, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 8, + }, { + .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 8 + }, { + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 8, + }, { + .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 8, + }, }; -static const struct ov5640_pixfmt ov5640_formats[] = { - { MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, }, - { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_UYVY8_1X16, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_YUYV8_1X16, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_COLORSPACE_SRGB, }, - { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_COLORSPACE_SRGB, }, -}; +static u32 ov5640_code_to_bpp(u32 code) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ov5640_formats); ++i) { + if (ov5640_formats[i].code == code) + return ov5640_formats[i].bpp; + } + + return 0; +} /* * FIXME: remove this when a subdev API becomes available From patchwork Thu Feb 10 11:04:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541632 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21CBAC433FE for ; Thu, 10 Feb 2022 11:04:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240482AbiBJLER (ORCPT ); Thu, 10 Feb 2022 06:04:17 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240489AbiBJLEO (ORCPT ); Thu, 10 Feb 2022 06:04:14 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11E6D100B for ; Thu, 10 Feb 2022 03:04:15 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id C8684200010; Thu, 10 Feb 2022 11:04:10 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 05/23] media: ov5640: Add LINK_FREQ control Date: Thu, 10 Feb 2022 12:04:40 +0100 Message-Id: <20220210110458.152494-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add the V4L2_CID_LINK_FREQ control to the ov5640 driver. Make the control read-only for the moment. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 71404d064045..4c3a1fd41095 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -141,6 +141,21 @@ static const u32 ov5640_pixel_rates[] = { [OV5640_PIXEL_RATE_48M] = 48000000, }; +/* + * MIPI CSI-2 link frequencies. + * + * Derived from the above defined pixel rate for bpp = (8, 16, 24) and + * data_lanes = (1, 2) + * + * link_freq = (pixel_rate * bpp) / (2 * data_lanes) + */ +static const s64 ov5640_csi2_link_freqs[] = { + 992000000, 888000000, 768000000, 744000000, 672000000, 672000000, + 592000000, 592000000, 576000000, 576000000, 496000000, 496000000, + 384000000, 384000000, 384000000, 336000000, 296000000, 288000000, + 248000000, 192000000, 192000000, 192000000, 96000000, +}; + enum ov5640_format_mux { OV5640_FMT_MUX_YUV422 = 0, OV5640_FMT_MUX_RGB, @@ -270,6 +285,7 @@ struct ov5640_mode_info { struct ov5640_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *pixel_rate; + struct v4l2_ctrl *link_freq; struct { struct v4l2_ctrl *auto_exp; struct v4l2_ctrl *exposure; @@ -2867,6 +2883,11 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) ov5640_pixel_rates[0], 1, ov5640_pixel_rates[mode->pixel_rate]); + ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(ov5640_csi2_link_freqs) - 1, + 4, ov5640_csi2_link_freqs); + /* Auto/manual white balance */ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, @@ -2915,6 +2936,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) } ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; From patchwork Thu Feb 10 11:04:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541986 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 781DBC433EF for ; Thu, 10 Feb 2022 11:04:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240485AbiBJLES (ORCPT ); Thu, 10 Feb 2022 06:04:18 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLER (ORCPT ); Thu, 10 Feb 2022 06:04:17 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DDBEFFF for ; Thu, 10 Feb 2022 03:04:18 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id B52A7200002; Thu, 10 Feb 2022 11:04:14 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 06/23] media: ov5640: Update pixel_rate and link_freq Date: Thu, 10 Feb 2022 12:04:41 +0100 Message-Id: <20220210110458.152494-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org After having set a new format re-calculate the pixel_rate and link_freq control values and update them when in MIPI mode. Take into account the limitation of the link frequency having to be strictly smaller than 1GHz when computing the desired link_freq, and adjust the resulting pixel_rate acounting for the clock tree configuration. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 66 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 4c3a1fd41095..50b611697470 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -31,6 +31,8 @@ #define OV5640_DEFAULT_SLAVE_ID 0x3c +#define OV5640_LINK_RATE_MAX 490000000U + #define OV5640_REG_SYS_RESET02 0x3002 #define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006 #define OV5640_REG_SYS_CTRL0 0x3008 @@ -2409,6 +2411,66 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, return 0; } +static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) +{ + const struct ov5640_mode_info *mode = sensor->current_mode; + struct v4l2_mbus_framefmt *fmt = &sensor->fmt; + enum ov5640_pixel_rate_id pixel_rate_id = mode->pixel_rate; + unsigned int i = 0; + u32 pixel_rate; + s64 link_freq; + u32 num_lanes; + u32 bpp; + + /* + * Update the pixel rate control value. + * + * For DVP mode, maintain the pixel rate calculation using fixed FPS. + */ + if (!ov5640_is_csi2(sensor)) { + __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, + ov5640_calc_pixel_rate(sensor)); + + return 0; + } + + /* + * The MIPI CSI-2 link frequency should comply with the CSI-2 + * specification and be lower than 1GHz. + * + * Start from the suggested pixel_rate for the current mode and + * progressively slow it down if it exceeds 1GHz. + */ + num_lanes = sensor->ep.bus.mipi_csi2.num_data_lanes; + bpp = ov5640_code_to_bpp(fmt->code); + do { + pixel_rate = ov5640_pixel_rates[pixel_rate_id]; + link_freq = pixel_rate * bpp / (2 * num_lanes); + } while (link_freq >= 1000000000U && + ++pixel_rate_id < OV5640_NUM_PIXEL_RATES); + + /* + * Higher link rates require the clock tree to be programmed with + * 'mipi_div' = 1; this has the effect of halving the actual output + * pixel rate in the MIPI domain. + * + * Adjust the pixel rate control value to report it correctly to + * userspace. + */ + if (link_freq > OV5640_LINK_RATE_MAX) + pixel_rate /= 2; + + for (i = 0; i < ARRAY_SIZE(ov5640_csi2_link_freqs); ++i) { + if (ov5640_csi2_link_freqs[i] == link_freq) + break; + } + + __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, pixel_rate); + __v4l2_ctrl_s_ctrl(sensor->ctrls.link_freq, i); + + return 0; +} + static int ov5640_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) @@ -2448,8 +2510,8 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd, /* update format even if code is unchanged, resolution might change */ sensor->fmt = *mbus_fmt; - __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, - ov5640_calc_pixel_rate(sensor)); + ov5640_update_pixel_rate(sensor); + out: mutex_unlock(&sensor->lock); return ret; From patchwork Thu Feb 10 11:04:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541631 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F831C433F5 for ; Thu, 10 Feb 2022 11:04:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240491AbiBJLEV (ORCPT ); Thu, 10 Feb 2022 06:04:21 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39626 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLEU (ORCPT ); Thu, 10 Feb 2022 06:04:20 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC5341008 for ; Thu, 10 Feb 2022 03:04:20 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 4FDFC20000E; Thu, 10 Feb 2022 11:04:17 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 07/23] media: ov5640: Rework CSI-2 clock tree Date: Thu, 10 Feb 2022 12:04:42 +0100 Message-Id: <20220210110458.152494-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Re-work the ov5640_set_mipi_pclk() function to calculate the PLL configuration using the pixel_rate and link_freq values set at s_fmt time. Rework the DVP clock mode settings to calculate the pixel clock internally and remove the assumption on the 16bpp format. Tested in MIPI CSI-2 mode with 1 and 2 data lanes with: - all the sensor supported resolutions in UYVY and RGB565 formats. - resolutions >= 1280x720 in RAW Bayer format. - resolutions < 1280x720 in RGB888 format. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5640.c | 189 ++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 99 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 50b611697470..eb4789ae6abf 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -90,6 +90,7 @@ #define OV5640_REG_POLARITY_CTRL00 0x4740 #define OV5640_REG_MIPI_CTRL00 0x4800 #define OV5640_REG_DEBUG_MODE 0x4814 +#define OV5640_REG_PCLK_PERIOD 0x4837 #define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f #define OV5640_REG_PRE_ISP_TEST_SET1 0x503d #define OV5640_REG_SDE_CTRL0 0x5580 @@ -922,20 +923,10 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg, * +-----+-----+ * +------------> PCLK * - * This is deviating from the datasheet at least for the register - * 0x3108, since it's said here that the PCLK would be clocked from - * the PLL. - * - * There seems to be also (unverified) constraints: + * There seems to be also constraints: * - the PLL pre-divider output rate should be in the 4-27MHz range * - the PLL multiplier output rate should be in the 500-1000MHz range * - PCLK >= SCLK * 2 in YUV, >= SCLK in Raw or JPEG - * - * In the two latter cases, these constraints are met since our - * factors are hardcoded. If we were to change that, we would need to - * take this into account. The only varying parts are the PLL - * multiplier and the system clock divider, which are shared between - * all these clocks so won't cause any issue. */ /* @@ -954,13 +945,6 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg, #define OV5640_SYSDIV_MIN 1 #define OV5640_SYSDIV_MAX 16 -/* - * Hardcode these values for scaler and non-scaler modes. - * FIXME: to be re-calcualted for 1 data lanes setups - */ -#define OV5640_MIPI_DIV_PCLK 2 -#define OV5640_MIPI_DIV_SCLK 1 - /* * This is supposed to be ranging from 1 to 2, but the value is always * set to 2 in the vendor kernels. @@ -1071,69 +1055,77 @@ static unsigned long ov5640_calc_sys_clk(struct ov5640_dev *sensor, * ov5640_set_mipi_pclk() - Calculate the clock tree configuration values * for the MIPI CSI-2 output. * - * @rate: The requested bandwidth per lane in bytes per second. - * 'Bandwidth Per Lane' is calculated as: - * bpl = HTOT * VTOT * FPS * bpp / num_lanes; - * - * This function use the requested bandwidth to calculate: - * - sample_rate = bpl / (bpp / num_lanes); - * = bpl / (PLL_RDIV * BIT_DIV * PCLK_DIV * MIPI_DIV / num_lanes); - * - * - mipi_sclk = bpl / MIPI_DIV / 2; ( / 2 is for CSI-2 DDR) - * - * with these fixed parameters: - * PLL_RDIV = 2; - * BIT_DIVIDER = 2; (MIPI_BIT_MODE == 8 ? 2 : 2,5); - * PCLK_DIV = 1; - * - * The MIPI clock generation differs for modes that use the scaler and modes - * that do not. In case the scaler is in use, the MIPI_SCLK generates the MIPI - * BIT CLk, and thus: - * - * - mipi_sclk = bpl / MIPI_DIV / 2; - * MIPI_DIV = 1; - * - * For modes that do not go through the scaler, the MIPI BIT CLOCK is generated - * from the pixel clock, and thus: - * - * - sample_rate = bpl / (bpp / num_lanes); - * = bpl / (2 * 2 * 1 * MIPI_DIV / num_lanes); - * = bpl / (4 * MIPI_DIV / num_lanes); - * - MIPI_DIV = bpp / (4 * num_lanes); - * - * FIXME: this have been tested with 16bpp and 2 lanes setup only. - * MIPI_DIV is fixed to value 2, but it -might- be changed according to the - * above formula for setups with 1 lane or image formats with different bpp. - * - * FIXME: this deviates from the sensor manual documentation which is quite - * thin on the MIPI clock tree generation part. + * FIXME: tested with 2 lanes only. */ -static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor, - unsigned long rate) +static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor) { - const struct ov5640_mode_info *mode = sensor->current_mode; + u8 bit_div, mipi_div, p_div, sclk_div, sclk2x_div, root_div; + struct v4l2_mbus_framefmt *fmt = &sensor->fmt; u8 prediv, mult, sysdiv; - u8 mipi_div; + unsigned long sysclk; + unsigned long sample_rate; + u8 pclk_period; + s64 link_freq; int ret; + /* Use the link frequency computed at ov5640_update_pixel_rate() time. */ + link_freq = ov5640_csi2_link_freqs[sensor->ctrls.link_freq->cur.val]; + /* - * 1280x720 is reported to use 'SUBSAMPLING' only, - * but according to the sensor manual it goes through the - * scaler before subsampling. + * - mipi_div - Additional divider for the MIPI lane clock. + * + * Higher link frequencies would make sysclk > 1GHz. + * Keep the sysclk low and do not divide in the MIPI domain. */ - if (mode->dn_mode == SCALING || - (mode->id == OV5640_MODE_720P_1280_720)) - mipi_div = OV5640_MIPI_DIV_SCLK; + if (link_freq > OV5640_LINK_RATE_MAX) + mipi_div = 1; else - mipi_div = OV5640_MIPI_DIV_PCLK; + mipi_div = 2; - ov5640_calc_sys_clk(sensor, rate, &prediv, &mult, &sysdiv); + sysclk = link_freq * mipi_div; + ov5640_calc_sys_clk(sensor, sysclk, &prediv, &mult, &sysdiv); - ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0, - 0x0f, OV5640_PLL_CTRL0_MIPI_MODE_8BIT); + /* + * Adjust PLL parameters to maintain the MIPI_SCLK-to-PCLK ratio; + * + * - root_div = 2 (fixed) + * - bit_div : MIPI 8-bit = 2 + * MIPI 10-bit = 2.5 + * - p_div = 1 (fixed) + * - pll_div = (2 lanes ? mipi_div : 2 * mipi_div) + * 2 lanes: MIPI_SCLK = (4 or 5) * PCLK + * 1 lanes: MIPI_SCLK = (8 or 10) * PCLK + */ + root_div = OV5640_PLL_CTRL3_PLL_ROOT_DIV_2; + bit_div = OV5640_PLL_CTRL0_MIPI_MODE_8BIT; + p_div = OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS; - ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1, - 0xff, sysdiv << 4 | mipi_div); + /* + * Scaler clock: + * - YUV: PCLK >= 2 * SCLK + * - RAW or JPEG: PCLK >= SCLK + * - sclk2x_div = sclk_div / 2 + * + * TODO: test with JPEG. + */ + sclk_div = ilog2(OV5640_SCLK_ROOT_DIV); + sclk2x_div = ilog2(OV5640_SCLK2X_ROOT_DIV); + + /* + * Set the sample period expressed in ns with 1-bit decimal + * (0x01=0.5ns). + */ + sample_rate = ov5640_pixel_rates[sensor->current_mode->pixel_rate] + * (ov5640_code_to_bpp(fmt->code) / 8); + pclk_period = 2000000000U / sample_rate; + + /* Program the clock tree registers. */ + ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0, 0x0f, bit_div); + if (ret) + return ret; + + ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1, 0xff, + (sysdiv << 4) | mipi_div); if (ret) return ret; @@ -1141,13 +1133,27 @@ static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor, if (ret) return ret; - ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3, - 0x1f, OV5640_PLL_CTRL3_PLL_ROOT_DIV_2 | prediv); + ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3, 0x1f, + root_div | prediv); + if (ret) + return ret; + + ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f, + (p_div << 4) | (sclk2x_div << 2) | sclk_div); if (ret) return ret; - return ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, - 0x30, OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS); + return ov5640_write_reg(sensor, OV5640_REG_PCLK_PERIOD, pclk_period); +} + +static u32 ov5640_calc_pixel_rate(struct ov5640_dev *sensor) +{ + u32 rate; + + rate = sensor->current_mode->vtot * sensor->current_mode->htot; + rate *= ov5640_framerates[sensor->current_fr]; + + return rate; } static unsigned long ov5640_calc_pclk(struct ov5640_dev *sensor, @@ -1167,11 +1173,16 @@ static unsigned long ov5640_calc_pclk(struct ov5640_dev *sensor, return _rate / *pll_rdiv / *bit_div / *pclk_div; } -static int ov5640_set_dvp_pclk(struct ov5640_dev *sensor, unsigned long rate) +static int ov5640_set_dvp_pclk(struct ov5640_dev *sensor) { u8 prediv, mult, sysdiv, pll_rdiv, bit_div, pclk_div; + u32 rate; int ret; + rate = ov5640_calc_pixel_rate(sensor); + rate *= ov5640_code_to_bpp(sensor->fmt.code); + rate /= sensor->ep.bus.parallel.bus_width; + ov5640_calc_pclk(sensor, rate, &prediv, &mult, &sysdiv, &pll_rdiv, &bit_div, &pclk_div); @@ -1696,16 +1707,6 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, return mode; } -static u64 ov5640_calc_pixel_rate(struct ov5640_dev *sensor) -{ - u64 rate; - - rate = sensor->current_mode->vtot * sensor->current_mode->htot; - rate *= ov5640_framerates[sensor->current_fr]; - - return rate; -} - /* * sensor changes between scaling and subsampling, go through * exposure calculation @@ -1887,7 +1888,6 @@ static int ov5640_set_mode(struct ov5640_dev *sensor) enum ov5640_downsize_mode dn_mode, orig_dn_mode; bool auto_gain = sensor->ctrls.auto_gain->val == 1; bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO; - unsigned long rate; int ret; dn_mode = mode->dn_mode; @@ -1906,19 +1906,10 @@ static int ov5640_set_mode(struct ov5640_dev *sensor) goto restore_auto_gain; } - /* - * All the formats we support have 16 bits per pixel, seems to require - * the same rate than YUV, so we can just use 16 bpp all the time. - */ - rate = ov5640_calc_pixel_rate(sensor) * 16; - if (ov5640_is_csi2(sensor)) { - rate = rate / sensor->ep.bus.mipi_csi2.num_data_lanes; - ret = ov5640_set_mipi_pclk(sensor, rate); - } else { - rate = rate / sensor->ep.bus.parallel.bus_width; - ret = ov5640_set_dvp_pclk(sensor, rate); - } - + if (ov5640_is_csi2(sensor)) + ret = ov5640_set_mipi_pclk(sensor); + else + ret = ov5640_set_dvp_pclk(sensor); if (ret < 0) return 0; From patchwork Thu Feb 10 11:04:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541985 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 736BBC433EF for ; Thu, 10 Feb 2022 11:04:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240494AbiBJLEY (ORCPT ); Thu, 10 Feb 2022 06:04:24 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240476AbiBJLEX (ORCPT ); Thu, 10 Feb 2022 06:04:23 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [IPv6:2001:4b98:dc4:8::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F07DE100B for ; Thu, 10 Feb 2022 03:04:23 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id CB8B8200009; Thu, 10 Feb 2022 11:04:19 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 08/23] media: ov5640: Rework timings programming Date: Thu, 10 Feb 2022 12:04:43 +0100 Message-Id: <20220210110458.152494-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The current definition of a sensor mode defines timings as follows: - hact, vact: Visible width and height - htot, vtot: Total sizes including blankings This makes difficult to clearly separate the visible sizes from the blankings and to make the vertical blanking programmable. Rework the sensor modes sizes definition to: - Report the analog crop sizes - Report the visible crop size - Report the total pixels per line as HBLANK is fixed - Report the VBLANK value to make it programmable Also modify the ov5640_set_timings() function to program all the windowing registers are remove them from the per-mode register-value tables. Do not change the timing values from the ones reported in the register tables to maintain bisectability. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 441 +++++++++++++++++++++++++------------ 1 file changed, 296 insertions(+), 145 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index eb4789ae6abf..9ba1b44d21f7 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -61,10 +61,16 @@ #define OV5640_REG_AEC_PK_MANUAL 0x3503 #define OV5640_REG_AEC_PK_REAL_GAIN 0x350a #define OV5640_REG_AEC_PK_VTS 0x350c +#define OV5640_REG_TIMING_HS 0x3800 +#define OV5640_REG_TIMING_VS 0x3802 +#define OV5640_REG_TIMING_HW 0x3804 +#define OV5640_REG_TIMING_VH 0x3806 #define OV5640_REG_TIMING_DVPHO 0x3808 #define OV5640_REG_TIMING_DVPVO 0x380a #define OV5640_REG_TIMING_HTS 0x380c #define OV5640_REG_TIMING_VTS 0x380e +#define OV5640_REG_TIMING_HOFFS 0x3810 +#define OV5640_REG_TIMING_VOFFS 0x3812 #define OV5640_REG_TIMING_TC_REG20 0x3820 #define OV5640_REG_TIMING_TC_REG21 0x3821 #define OV5640_REG_AEC_CTRL00 0x3a00 @@ -276,12 +282,17 @@ struct ov5640_mode_info { enum ov5640_mode_id id; enum ov5640_downsize_mode dn_mode; enum ov5640_pixel_rate_id pixel_rate; - u32 hact; + /* Analog crop rectangle. */ + struct v4l2_rect analog_crop; + /* Visibile crop: from analog crop top-left corner. */ + struct v4l2_rect crop; + /* Total pixels per line: crop.width + fixed hblank. */ u32 htot; - u32 vact; - u32 vtot; + /* Default vertical blanking: frame height = crop.height + vblank. */ + u32 vblank_def; const struct reg_value *reg_data; u32 reg_data_size; + /* DVP only; ignored in MIPI mode. */ u32 max_fps; }; @@ -387,11 +398,7 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = { {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -459,11 +466,7 @@ static const struct reg_value ov5640_setting_VGA_640_480[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -478,11 +481,7 @@ static const struct reg_value ov5640_setting_XGA_1024_768[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -497,11 +496,7 @@ static const struct reg_value ov5640_setting_QVGA_320_240[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -516,11 +511,7 @@ static const struct reg_value ov5640_setting_QQVGA_160_120[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -534,11 +525,7 @@ static const struct reg_value ov5640_setting_QCIF_176_144[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -553,11 +540,7 @@ static const struct reg_value ov5640_setting_NTSC_720_480[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -572,11 +555,7 @@ static const struct reg_value ov5640_setting_PAL_720_576[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -591,11 +570,7 @@ static const struct reg_value ov5640_setting_720P_1280_720[] = { {0x3c07, 0x07, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0}, + {0x3815, 0x31, 0, 0}, {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0}, {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0}, @@ -610,11 +585,7 @@ static const struct reg_value ov5640_setting_1080P_1920_1080[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x11, 0, 0}, - {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0}, + {0x3815, 0x11, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0}, {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -625,9 +596,6 @@ static const struct reg_value ov5640_setting_1080P_1920_1080[] = { {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, - {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0}, - {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0}, - {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0}, {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0}, @@ -641,11 +609,7 @@ static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x11, 0, 0}, - {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, - {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0}, - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0}, - {0x3810, 0x00, 0, 0}, - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0}, + {0x3815, 0x11, 0, 0}, {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0}, {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0}, {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, @@ -658,96 +622,250 @@ static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = { /* power-on sensor init reg table */ static const struct ov5640_mode_info ov5640_mode_init_data = { - 0, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 640, 1896, 480, 984, - ov5640_init_setting_30fps_VGA, - ARRAY_SIZE(ov5640_init_setting_30fps_VGA), - OV5640_30_FPS, + .id = 0, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_96M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 640, + .height = 480, + }, + .htot = 1896, + .vblank_def = 504, + .reg_data = ov5640_init_setting_30fps_VGA, + .reg_data_size = ARRAY_SIZE(ov5640_init_setting_30fps_VGA), + .max_fps = OV5640_30_FPS }; static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { { /* 160x120 */ - OV5640_MODE_QQVGA_160_120, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 160, 1896, 120, 984, - ov5640_setting_QQVGA_160_120, - ARRAY_SIZE(ov5640_setting_QQVGA_160_120), - OV5640_30_FPS + .id = OV5640_MODE_QQVGA_160_120, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_48M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 160, + .height = 120, + }, + .htot = 1896, + .vblank_def = 864, + .reg_data = ov5640_setting_QQVGA_160_120, + .reg_data_size = ARRAY_SIZE(ov5640_setting_QQVGA_160_120), + .max_fps = OV5640_30_FPS }, { /* 176x144 */ - OV5640_MODE_QCIF_176_144, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 176, 1896, 144, 984, - ov5640_setting_QCIF_176_144, - ARRAY_SIZE(ov5640_setting_QCIF_176_144), - OV5640_30_FPS + .id = OV5640_MODE_QCIF_176_144, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_48M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 176, + .height = 144, + }, + .htot = 1896, + .vblank_def = 840, + .reg_data = ov5640_setting_QCIF_176_144, + .reg_data_size = ARRAY_SIZE(ov5640_setting_QCIF_176_144), + .max_fps = OV5640_30_FPS }, { /* 320x240 */ - OV5640_MODE_QVGA_320_240, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 320, 1896, 240, 984, - ov5640_setting_QVGA_320_240, - ARRAY_SIZE(ov5640_setting_QVGA_320_240), - OV5640_30_FPS + .id = OV5640_MODE_QVGA_320_240, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_48M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 320, + .height = 240, + }, + .htot = 1896, + .vblank_def = 744, + .reg_data = ov5640_setting_QVGA_320_240, + .reg_data_size = ARRAY_SIZE(ov5640_setting_QVGA_320_240), + .max_fps = OV5640_30_FPS }, { /* 640x480 */ - OV5640_MODE_VGA_640_480, SUBSAMPLING, - OV5640_PIXEL_RATE_48M, - 640, 1896, 480, 1080, - ov5640_setting_VGA_640_480, - ARRAY_SIZE(ov5640_setting_VGA_640_480), - OV5640_60_FPS + .id = OV5640_MODE_VGA_640_480, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_48M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 640, + .height = 480, + }, + .htot = 1896, + .vblank_def = 600, + .reg_data = ov5640_setting_VGA_640_480, + .reg_data_size = ARRAY_SIZE(ov5640_setting_VGA_640_480), + .max_fps = OV5640_60_FPS }, { /* 720x480 */ - OV5640_MODE_NTSC_720_480, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 720, 1896, 480, 984, - ov5640_setting_NTSC_720_480, - ARRAY_SIZE(ov5640_setting_NTSC_720_480), - OV5640_30_FPS + .id = OV5640_MODE_NTSC_720_480, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_96M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 60, + .width = 720, + .height = 480, + }, + .htot = 1896, + .vblank_def = 504, + .reg_data = ov5640_setting_NTSC_720_480, + .reg_data_size = ARRAY_SIZE(ov5640_setting_NTSC_720_480), + .max_fps = OV5640_30_FPS }, { /* 720x576 */ - OV5640_MODE_PAL_720_576, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 720, 1896, 576, 984, - ov5640_setting_PAL_720_576, - ARRAY_SIZE(ov5640_setting_PAL_720_576), - OV5640_30_FPS + .id = OV5640_MODE_PAL_720_576, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_96M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 56, + .top = 6, + .width = 720, + .height = 576, + }, + .htot = 1896, + .vblank_def = 408, + .reg_data = ov5640_setting_PAL_720_576, + .reg_data_size = ARRAY_SIZE(ov5640_setting_PAL_720_576), + .max_fps = OV5640_30_FPS }, { /* 1024x768 */ - OV5640_MODE_XGA_1024_768, SUBSAMPLING, - OV5640_PIXEL_RATE_96M, - 1024, 1896, 768, 1080, - ov5640_setting_XGA_1024_768, - ARRAY_SIZE(ov5640_setting_XGA_1024_768), - OV5640_30_FPS + .id = OV5640_MODE_XGA_1024_768, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_96M, + .analog_crop = { + .left = 0, + .top = 4, + .width = 2623, + .height = 1947, + }, + .crop = { + .left = 16, + .top = 6, + .width = 1024, + .height = 768, + }, + .htot = 1896, + .vblank_def = 312, + .reg_data = ov5640_setting_XGA_1024_768, + .reg_data_size = ARRAY_SIZE(ov5640_setting_XGA_1024_768), + .max_fps = OV5640_30_FPS }, { /* 1280x720 */ - OV5640_MODE_720P_1280_720, SUBSAMPLING, - OV5640_PIXEL_RATE_124M, - 1280, 1892, 720, 740, - ov5640_setting_720P_1280_720, - ARRAY_SIZE(ov5640_setting_720P_1280_720), - OV5640_30_FPS + .id = OV5640_MODE_720P_1280_720, + .dn_mode = SUBSAMPLING, + .pixel_rate = OV5640_PIXEL_RATE_124M, + .analog_crop = { + .left = 0, + .top = 250, + .width = 2623, + .height = 1705, + }, + .crop = { + .left = 16, + .top = 4, + .width = 1280, + .height = 720, + }, + .htot = 1892, + .vblank_def = 20, + .reg_data = ov5640_setting_720P_1280_720, + .reg_data_size = ARRAY_SIZE(ov5640_setting_720P_1280_720), + .max_fps = OV5640_30_FPS }, { /* 1920x1080 */ - OV5640_MODE_1080P_1920_1080, SCALING, - OV5640_PIXEL_RATE_148M, - 1920, 2500, 1080, 1120, - ov5640_setting_1080P_1920_1080, - ARRAY_SIZE(ov5640_setting_1080P_1920_1080), - OV5640_30_FPS + .id = OV5640_MODE_1080P_1920_1080, + .dn_mode = SCALING, + .pixel_rate = OV5640_PIXEL_RATE_148M, + .analog_crop = { + .left = 336, + .top = 434, + .width = 2287, + .height = 1521, + }, + .crop = { + .left = 16, + .top = 4, + .width = 1920, + .height = 1080, + }, + .htot = 2500, + .vblank_def = 40, + .reg_data = ov5640_setting_1080P_1920_1080, + .reg_data_size = ARRAY_SIZE(ov5640_setting_1080P_1920_1080), + .max_fps = OV5640_30_FPS }, { /* 2592x1944 */ - OV5640_MODE_QSXGA_2592_1944, SCALING, - OV5640_PIXEL_RATE_168M, - 2592, 2844, 1944, 1968, - ov5640_setting_QSXGA_2592_1944, - ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), - OV5640_15_FPS + .id = OV5640_MODE_QSXGA_2592_1944, + .dn_mode = SCALING, + .pixel_rate = OV5640_PIXEL_RATE_168M, + .analog_crop = { + .left = 0, + .top = 0, + .width = 2623, + .height = 1951, + }, + .crop = { + .left = 16, + .top = 4, + .width = 2592, + .height = 1944, + }, + .htot = 2844, + .vblank_def = 24, + .reg_data = ov5640_setting_QSXGA_2592_1944, + .reg_data_size = ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), + .max_fps = OV5640_15_FPS }, }; @@ -1150,7 +1268,8 @@ static u32 ov5640_calc_pixel_rate(struct ov5640_dev *sensor) { u32 rate; - rate = sensor->current_mode->vtot * sensor->current_mode->htot; + rate = sensor->current_mode->htot + * (sensor->current_mode->crop.height + sensor->current_mode->vblank_def); rate *= ov5640_framerates[sensor->current_fr]; return rate; @@ -1234,17 +1353,21 @@ static int ov5640_set_jpeg_timings(struct ov5640_dev *sensor, if (ret < 0) return ret; - ret = ov5640_write_reg16(sensor, OV5640_REG_VFIFO_HSIZE, mode->hact); + ret = ov5640_write_reg16(sensor, OV5640_REG_VFIFO_HSIZE, + mode->crop.width); if (ret < 0) return ret; - return ov5640_write_reg16(sensor, OV5640_REG_VFIFO_VSIZE, mode->vact); + return ov5640_write_reg16(sensor, OV5640_REG_VFIFO_VSIZE, + mode->crop.height); } /* download ov5640 settings to sensor through i2c */ static int ov5640_set_timings(struct ov5640_dev *sensor, const struct ov5640_mode_info *mode) { + const struct v4l2_rect *analog_crop = &mode->analog_crop; + const struct v4l2_rect *crop = &mode->crop; int ret; if (sensor->fmt.code == MEDIA_BUS_FMT_JPEG_1X8) { @@ -1253,11 +1376,35 @@ static int ov5640_set_timings(struct ov5640_dev *sensor, return ret; } - ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact); + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HS, analog_crop->left); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VS, analog_crop->top); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HW, analog_crop->width); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VH, analog_crop->height); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HOFFS, crop->left); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VOFFS, crop->top); + if (ret < 0) + return ret; + + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, crop->width); if (ret < 0) return ret; - ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact); + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, crop->height); if (ret < 0) return ret; @@ -1265,7 +1412,12 @@ static int ov5640_set_timings(struct ov5640_dev *sensor, if (ret < 0) return ret; - return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot); + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, + crop->height + mode->vblank_def); + if (ret < 0) + return ret; + + return 0; } static int ov5640_load_regs(struct ov5640_dev *sensor, @@ -1693,11 +1845,11 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, mode = v4l2_find_nearest_size(ov5640_mode_data, ARRAY_SIZE(ov5640_mode_data), - hact, vact, - width, height); + crop.width, crop.height, width, height); if (!mode || - (!nearest && (mode->hact != width || mode->vact != height))) + (!nearest && + (mode->crop.width != width || mode->crop.height != height))) return NULL; /* Check to see if the current mode exceeds the max frame rate */ @@ -2381,8 +2533,8 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true); if (!mode) return -EINVAL; - fmt->width = mode->hact; - fmt->height = mode->vact; + fmt->width = mode->crop.width; + fmt->height = mode->crop.height; if (new_mode) *new_mode = mode; @@ -3014,11 +3166,9 @@ static int ov5640_enum_frame_size(struct v4l2_subdev *sd, if (fse->index >= OV5640_NUM_MODES) return -EINVAL; - fse->min_width = - ov5640_mode_data[fse->index].hact; + fse->min_width = ov5640_mode_data[fse->index].crop.width; fse->max_width = fse->min_width; - fse->min_height = - ov5640_mode_data[fse->index].vact; + fse->min_height = ov5640_mode_data[fse->index].crop.height; fse->max_height = fse->min_height; return 0; @@ -3082,15 +3232,16 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd, mode = sensor->current_mode; frame_rate = ov5640_try_frame_interval(sensor, &fi->interval, - mode->hact, mode->vact); + mode->crop.width, + mode->crop.height); if (frame_rate < 0) { /* Always return a valid frame interval value */ fi->interval = sensor->frame_interval; goto out; } - mode = ov5640_find_mode(sensor, frame_rate, mode->hact, - mode->vact, true); + mode = ov5640_find_mode(sensor, frame_rate, mode->crop.width, + mode->crop.height, true); if (!mode) { ret = -EINVAL; goto out; From patchwork Thu Feb 10 11:04:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541630 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88109C433FE for ; Thu, 10 Feb 2022 11:04:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240496AbiBJLEZ (ORCPT ); Thu, 10 Feb 2022 06:04:25 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234177AbiBJLEY (ORCPT ); Thu, 10 Feb 2022 06:04:24 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65C0A1008 for ; Thu, 10 Feb 2022 03:04:26 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9A5B6200003; Thu, 10 Feb 2022 11:04:22 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 09/23] media: ov5640: Fix 720x480 in RGB888 mode Date: Thu, 10 Feb 2022 12:04:44 +0100 Message-Id: <20220210110458.152494-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Adjust the left crop of 720x480 to enable capture in RGB888 format, which is otherwise broken. The 56 pixels alignment has been copied from the 720x576 mode. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 9ba1b44d21f7..f817f865ad16 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -746,7 +746,7 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .height = 1947, }, .crop = { - .left = 16, + .left = 56, .top = 60, .width = 720, .height = 480, From patchwork Thu Feb 10 11:04:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541984 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9CF0C433EF for ; Thu, 10 Feb 2022 11:04:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240501AbiBJLEa (ORCPT ); Thu, 10 Feb 2022 06:04:30 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39706 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234177AbiBJLE2 (ORCPT ); Thu, 10 Feb 2022 06:04:28 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 78A9AFFF for ; Thu, 10 Feb 2022 03:04:29 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 51C3720000E; Thu, 10 Feb 2022 11:04:25 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 10/23] media: ov5640: Rework analog crop rectangles Date: Thu, 10 Feb 2022 12:04:45 +0100 Message-Id: <20220210110458.152494-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The OV5640 pixel array is composed as: - vertically: 16 dummy columns, 1944 valid ones and 16 dummy columns - horizontally: 8 optical black lines, 6 dummy ones, 2592 valid and 6 dummies Adjust the analog crop rectangle in all modes to: - Skip the first 16 dummy columns - Skip the first 14 black/dummy lines - Pass the whole valid pixel array size to the ISP for all modes except 1920x1080 which is obtained by cropping the valid pixel array. Adjust how timings is programmed to comply with the new definitions. Tested in RGB565, UYVY, RGB565 and RGB888 modes. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5640.c | 138 +++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index f817f865ad16..72b78201f089 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -626,14 +626,14 @@ static const struct ov5640_mode_info ov5640_mode_init_data = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_96M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + .left = 2, + .top = 4, .width = 640, .height = 480, }, @@ -644,22 +644,23 @@ static const struct ov5640_mode_info ov5640_mode_init_data = { .max_fps = OV5640_30_FPS }; -static const struct ov5640_mode_info -ov5640_mode_data[OV5640_NUM_MODES] = { +static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { { /* 160x120 */ .id = OV5640_MODE_QQVGA_160_120, .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_48M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, + .top = 4, .width = 160, .height = 120, }, @@ -674,14 +675,16 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_48M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, + .top = 4, .width = 176, .height = 144, }, @@ -696,14 +699,16 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_48M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, + .top = 4, .width = 320, .height = 240, }, @@ -718,14 +723,16 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_48M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, + .top = 4, .width = 640, .height = 480, }, @@ -740,12 +747,14 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_96M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { + /* Maintain a minimum digital crop processing margins. */ .left = 56, .top = 60, .width = 720, @@ -762,12 +771,14 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_96M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { + /* Maintain a minimum digital crop processing margins. */ .left = 56, .top = 6, .width = 720, @@ -784,14 +795,16 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_96M, .analog_crop = { - .left = 0, - .top = 4, - .width = 2623, - .height = 1947, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, - .top = 6, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, + .top = 4, .width = 1024, .height = 768, }, @@ -806,13 +819,15 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SUBSAMPLING, .pixel_rate = OV5640_PIXEL_RATE_124M, .analog_crop = { - .left = 0, - .top = 250, - .width = 2623, - .height = 1705, + /* Feed the full valid pixel array to the ISP. */ + .left = OV5640_PIXEL_ARRAY_LEFT, + .top = OV5640_PIXEL_ARRAY_TOP, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .crop = { - .left = 16, + /* Maintain a minimum digital crop processing margins. */ + .left = 2, .top = 4, .width = 1280, .height = 720, @@ -828,12 +843,14 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SCALING, .pixel_rate = OV5640_PIXEL_RATE_148M, .analog_crop = { + /* Crop the full valid pixel array in the center. */ .left = 336, .top = 434, - .width = 2287, - .height = 1521, + .width = 1952, + .height = 1088, }, .crop = { + /* Maintain a larger digital crop processing margins. */ .left = 16, .top = 4, .width = 1920, @@ -850,16 +867,17 @@ ov5640_mode_data[OV5640_NUM_MODES] = { .dn_mode = SCALING, .pixel_rate = OV5640_PIXEL_RATE_168M, .analog_crop = { + /* Give more processing margin to full resolution. */ .left = 0, .top = 0, - .width = 2623, - .height = 1951, + .width = OV5640_NATIVE_WIDTH, + .height = 1952, }, .crop = { .left = 16, .top = 4, - .width = 2592, - .height = 1944, + .width = OV5640_PIXEL_ARRAY_WIDTH, + .height = OV5640_PIXEL_ARRAY_HEIGHT, }, .htot = 2844, .vblank_def = 24, @@ -1384,11 +1402,13 @@ static int ov5640_set_timings(struct ov5640_dev *sensor, if (ret < 0) return ret; - ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HW, analog_crop->width); + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HW, + analog_crop->width + analog_crop->left - 1); if (ret < 0) return ret; - ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VH, analog_crop->height); + ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VH, + analog_crop->height + analog_crop->top - 1); if (ret < 0) return ret; From patchwork Thu Feb 10 11:04:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D32CEC433EF for ; Thu, 10 Feb 2022 11:04:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240504AbiBJLEc (ORCPT ); Thu, 10 Feb 2022 06:04:32 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234177AbiBJLEb (ORCPT ); Thu, 10 Feb 2022 06:04:31 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F8A51010 for ; Thu, 10 Feb 2022 03:04:31 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 5A833200008; Thu, 10 Feb 2022 11:04:28 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 11/23] media: ov5640: Re-sort per-mode register tables Date: Thu, 10 Feb 2022 12:04:46 +0100 Message-Id: <20220210110458.152494-12-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The per-mode register tables are not sorted by size. Fix it. Cosmetic change only. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 72b78201f089..17835e71665a 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -462,7 +462,7 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = { {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300}, }; -static const struct reg_value ov5640_setting_VGA_640_480[] = { +static const struct reg_value ov5640_setting_QQVGA_160_120[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -473,11 +473,10 @@ static const struct reg_value ov5640_setting_VGA_640_480[] = { {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0}, }; -static const struct reg_value ov5640_setting_XGA_1024_768[] = { +static const struct reg_value ov5640_setting_QCIF_176_144[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -507,7 +506,7 @@ static const struct reg_value ov5640_setting_QVGA_320_240[] = { {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, }; -static const struct reg_value ov5640_setting_QQVGA_160_120[] = { +static const struct reg_value ov5640_setting_VGA_640_480[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -518,10 +517,11 @@ static const struct reg_value ov5640_setting_QQVGA_160_120[] = { {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, }; -static const struct reg_value ov5640_setting_QCIF_176_144[] = { +static const struct reg_value ov5640_setting_NTSC_720_480[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -536,7 +536,7 @@ static const struct reg_value ov5640_setting_QCIF_176_144[] = { {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, }; -static const struct reg_value ov5640_setting_NTSC_720_480[] = { +static const struct reg_value ov5640_setting_PAL_720_576[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, @@ -551,7 +551,7 @@ static const struct reg_value ov5640_setting_NTSC_720_480[] = { {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, }; -static const struct reg_value ov5640_setting_PAL_720_576[] = { +static const struct reg_value ov5640_setting_XGA_1024_768[] = { {0x3c07, 0x08, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, {0x3814, 0x31, 0, 0}, From patchwork Thu Feb 10 11:04:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541983 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FFFDC433FE for ; Thu, 10 Feb 2022 11:04:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240520AbiBJLEd (ORCPT ); Thu, 10 Feb 2022 06:04:33 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240499AbiBJLEd (ORCPT ); Thu, 10 Feb 2022 06:04:33 -0500 Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99A8EFFF for ; Thu, 10 Feb 2022 03:04:34 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 13622200011; Thu, 10 Feb 2022 11:04:30 +0000 (UTC) From: Jacopo Mondi To: Steve Longerbeam Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, Eugen.Hristev@microchip.com, jbrunet@baylibre.com, Mauro Carvalho Chehab , linux-media@vger.kernel.org Subject: [PATCH v2 12/23] media: ov5640: Remove ov5640_mode_init_data Date: Thu, 10 Feb 2022 12:04:47 +0100 Message-Id: <20220210110458.152494-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ov5640_mode_init_data is a fictional sensor more which is used to program the initial sensor settings. It is only used to initialize the sensor and can be replaced it with a throw-away mode which just wraps the register table. Also rename the register table to drop the format from the name to make it clear an actual sensor mode has to be applied after the initial programming. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 47 ++++++++------------------------------ 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 17835e71665a..2a922224ca9d 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -382,7 +382,7 @@ static inline bool ov5640_is_csi2(struct ov5640_dev *sensor) * over i2c. */ /* YUV422 UYVY VGA@30fps */ -static const struct reg_value ov5640_init_setting_30fps_VGA[] = { +static const struct reg_value ov5640_init_setting[] = { {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0}, @@ -620,30 +620,6 @@ static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = { {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 70}, }; -/* power-on sensor init reg table */ -static const struct ov5640_mode_info ov5640_mode_init_data = { - .id = 0, - .dn_mode = SUBSAMPLING, - .pixel_rate = OV5640_PIXEL_RATE_96M, - .analog_crop = { - .left = OV5640_PIXEL_ARRAY_LEFT, - .top = OV5640_PIXEL_ARRAY_TOP, - .width = OV5640_PIXEL_ARRAY_WIDTH, - .height = OV5640_PIXEL_ARRAY_HEIGHT, - }, - .crop = { - .left = 2, - .top = 4, - .width = 640, - .height = 480, - }, - .htot = 1896, - .vblank_def = 504, - .reg_data = ov5640_init_setting_30fps_VGA, - .reg_data_size = ARRAY_SIZE(ov5640_init_setting_30fps_VGA), - .max_fps = OV5640_30_FPS -}; - static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { { /* 160x120 */ @@ -1440,17 +1416,16 @@ static int ov5640_set_timings(struct ov5640_dev *sensor, return 0; } -static int ov5640_load_regs(struct ov5640_dev *sensor, - const struct ov5640_mode_info *mode) +static void ov5640_load_regs(struct ov5640_dev *sensor, + const struct reg_value *regs, unsigned int regnum) { - const struct reg_value *regs = mode->reg_data; unsigned int i; u32 delay_ms; u16 reg_addr; u8 mask, val; int ret = 0; - for (i = 0; i < mode->reg_data_size; ++i, ++regs) { + for (i = 0; i < regnum; ++i, ++regs) { delay_ms = regs->delay_ms; reg_addr = regs->reg_addr; val = regs->val; @@ -1472,8 +1447,6 @@ static int ov5640_load_regs(struct ov5640_dev *sensor, if (delay_ms) usleep_range(1000 * delay_ms, 1000 * delay_ms + 100); } - - return ov5640_set_timings(sensor, mode); } static int ov5640_set_autoexposure(struct ov5640_dev *sensor, bool on) @@ -1926,7 +1899,8 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor, return ret; /* Write capture setting */ - ret = ov5640_load_regs(sensor, mode); + ov5640_load_regs(sensor, mode->reg_data, mode->reg_data_size); + ret = ov5640_set_timings(sensor, mode); if (ret < 0) return ret; @@ -2050,7 +2024,8 @@ static int ov5640_set_mode_direct(struct ov5640_dev *sensor, return -EINVAL; /* Write capture setting */ - return ov5640_load_regs(sensor, mode); + ov5640_load_regs(sensor, mode->reg_data, mode->reg_data_size); + return ov5640_set_timings(sensor, mode); } static int ov5640_set_mode(struct ov5640_dev *sensor) @@ -2148,10 +2123,8 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor) int ret; /* first load the initial register values */ - ret = ov5640_load_regs(sensor, &ov5640_mode_init_data); - if (ret < 0) - return ret; - sensor->last_mode = &ov5640_mode_init_data; + ov5640_load_regs(sensor, ov5640_init_setting, + ARRAY_SIZE(ov5640_init_setting)); ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f, (ilog2(OV5640_SCLK2X_ROOT_DIV) << 2) | From patchwork Thu Feb 10 11:09:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B835FC433F5 for ; Thu, 10 Feb 2022 11:09:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240561AbiBJLJJ (ORCPT ); Thu, 10 Feb 2022 06:09:09 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237987AbiBJLJI (ORCPT ); Thu, 10 Feb 2022 06:09:08 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3DAAF128 for ; Thu, 10 Feb 2022 03:09:09 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6A1991C0008; Thu, 10 Feb 2022 11:09:03 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 13/23] media: ov5640: Add HBLANK control Date: Thu, 10 Feb 2022 12:09:58 +0100 Message-Id: <20220210111004.152859-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add the HBLANK control as read-only. The hblank value is fixed in the mode definition and is updated everytime a new format is applied. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 2a922224ca9d..ade9adb43fda 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -300,6 +300,7 @@ struct ov5640_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *pixel_rate; struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *hblank; struct { struct v4l2_ctrl *auto_exp; struct v4l2_ctrl *exposure; @@ -2552,6 +2553,7 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) const struct ov5640_mode_info *mode = sensor->current_mode; struct v4l2_mbus_framefmt *fmt = &sensor->fmt; enum ov5640_pixel_rate_id pixel_rate_id = mode->pixel_rate; + unsigned int hblank; unsigned int i = 0; u32 pixel_rate; s64 link_freq; @@ -2604,6 +2606,10 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, pixel_rate); __v4l2_ctrl_s_ctrl(sensor->ctrls.link_freq, i); + hblank = mode->htot - mode->crop.width; + __v4l2_ctrl_modify_range(sensor->ctrls.hblank, + hblank, hblank, 1, hblank); + return 0; } @@ -3068,6 +3074,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops; struct ov5640_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; + unsigned int hblank; int ret; v4l2_ctrl_handler_init(hdl, 32); @@ -3086,6 +3093,10 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) ARRAY_SIZE(ov5640_csi2_link_freqs) - 1, 4, ov5640_csi2_link_freqs); + hblank = mode->htot - mode->crop.width; + ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, hblank, + hblank, 1, hblank); + /* Auto/manual white balance */ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, @@ -3135,6 +3146,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; From patchwork Thu Feb 10 11:09:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541982 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94C0AC433F5 for ; Thu, 10 Feb 2022 11:09:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240565AbiBJLJM (ORCPT ); Thu, 10 Feb 2022 06:09:12 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237987AbiBJLJL (ORCPT ); Thu, 10 Feb 2022 06:09:11 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58B12B71 for ; Thu, 10 Feb 2022 03:09:12 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id C944B1C0012; Thu, 10 Feb 2022 11:09:07 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 14/23] media: ov5640: Add VBLANK control Date: Thu, 10 Feb 2022 12:09:59 +0100 Message-Id: <20220210111004.152859-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add the VBLANK control which allows to select the duration of the frame vertical blankings and allows to control the framerate. The VBLANK control also modifies the exposure time range, which cannot exceed the maximum frame length. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index ade9adb43fda..30b706a98eb9 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -29,6 +29,12 @@ #define OV5640_XCLK_MIN 6000000 #define OV5640_XCLK_MAX 54000000 +#define OV5640_LINK_RATE_MAX 490000000U + +/* FIXME: not documented. */ +#define OV5640_MIN_VBLANK 24 +#define OV5640_MAX_VTS 1968 + #define OV5640_DEFAULT_SLAVE_ID 0x3c #define OV5640_LINK_RATE_MAX 490000000U @@ -301,6 +307,7 @@ struct ov5640_ctrls { struct v4l2_ctrl *pixel_rate; struct v4l2_ctrl *link_freq; struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; struct { struct v4l2_ctrl *auto_exp; struct v4l2_ctrl *exposure; @@ -2553,6 +2560,7 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) const struct ov5640_mode_info *mode = sensor->current_mode; struct v4l2_mbus_framefmt *fmt = &sensor->fmt; enum ov5640_pixel_rate_id pixel_rate_id = mode->pixel_rate; + s64 exposure_val, exposure_max; unsigned int hblank; unsigned int i = 0; u32 pixel_rate; @@ -2610,6 +2618,20 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1, hblank); + __v4l2_ctrl_modify_range(sensor->ctrls.vblank, + OV5640_MIN_VBLANK, + OV5640_MAX_VTS - mode->crop.height, 1, + mode->vblank_def); + __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, mode->vblank_def); + + exposure_max = mode->crop.height + mode->vblank_def - 4; + exposure_val = clamp((s64)sensor->ctrls.exposure->val, + (s64)sensor->ctrls.exposure->minimum, + (s64)exposure_max); + __v4l2_ctrl_modify_range(sensor->ctrls.exposure, + sensor->ctrls.exposure->minimum, + exposure_max, 1, exposure_val); + return 0; } @@ -2982,6 +3004,15 @@ static int ov5640_set_ctrl_vflip(struct ov5640_dev *sensor, int value) (BIT(2) | BIT(1)) : 0); } +static int ov5640_set_ctrl_vblank(struct ov5640_dev *sensor, int value) +{ + const struct ov5640_mode_info *mode = sensor->current_mode; + + /* Update the VTOT timing register value. */ + return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, + mode->crop.height + value); +} + static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); @@ -3012,10 +3043,23 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); struct ov5640_dev *sensor = to_ov5640_dev(sd); + const struct ov5640_mode_info *mode = sensor->current_mode; + unsigned int exp_max; int ret; /* v4l2_ctrl_lock() locks our own mutex */ + switch (ctrl->id) { + case V4L2_CID_VBLANK: + /* Update the exposure range to the newly programmed vblank. */ + exp_max = mode->crop.height + ctrl->val - 4; + __v4l2_ctrl_modify_range(sensor->ctrls.exposure, + sensor->ctrls.exposure->minimum, + exp_max, sensor->ctrls.exposure->step, + mode->vblank_def); + break; + } + /* * If the device is not powered up by the host driver do * not apply any controls to H/W at this time. Instead @@ -3055,6 +3099,9 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_VFLIP: ret = ov5640_set_ctrl_vflip(sensor, ctrl->val); break; + case V4L2_CID_VBLANK: + ret = ov5640_set_ctrl_vblank(sensor, ctrl->val); + break; default: ret = -EINVAL; break; @@ -3074,6 +3121,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops; struct ov5640_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; + unsigned int max_vblank; unsigned int hblank; int ret; @@ -3097,6 +3145,11 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, hblank, hblank, 1, hblank); + max_vblank = OV5640_MAX_VTS - mode->crop.height; + ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, + OV5640_MIN_VBLANK, max_vblank, + 1, mode->vblank_def); + /* Auto/manual white balance */ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, From patchwork Thu Feb 10 11:10:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 062B2C433F5 for ; Thu, 10 Feb 2022 11:09:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240572AbiBJLJP (ORCPT ); Thu, 10 Feb 2022 06:09:15 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237987AbiBJLJO (ORCPT ); Thu, 10 Feb 2022 06:09:14 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82054128 for ; Thu, 10 Feb 2022 03:09:15 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 149751C0007; Thu, 10 Feb 2022 11:09:10 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 15/23] media: ov5640: Fix durations to comply with FPS Date: Thu, 10 Feb 2022 12:10:00 +0100 Message-Id: <20220210111004.152859-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Now that the frame duration can be controlled by tuning the VBLANK duration, fix all modes to comply with the reported FPS. All modes run at 30 FPS except for full-resolution mode 2592x1944 which runs at 15FPS. Tested on a 2 data lanes setup in UYVY and RGB565 modes. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 30b706a98eb9..dd7ff1bb580f 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -648,8 +648,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 160, .height = 120, }, - .htot = 1896, - .vblank_def = 864, + .htot = 1600, + .vblank_def = 878, .reg_data = ov5640_setting_QQVGA_160_120, .reg_data_size = ARRAY_SIZE(ov5640_setting_QQVGA_160_120), .max_fps = OV5640_30_FPS @@ -672,8 +672,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 176, .height = 144, }, - .htot = 1896, - .vblank_def = 840, + .htot = 1600, + .vblank_def = 854, .reg_data = ov5640_setting_QCIF_176_144, .reg_data_size = ARRAY_SIZE(ov5640_setting_QCIF_176_144), .max_fps = OV5640_30_FPS @@ -696,8 +696,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 320, .height = 240, }, - .htot = 1896, - .vblank_def = 744, + .htot = 1600, + .vblank_def = 760, .reg_data = ov5640_setting_QVGA_320_240, .reg_data_size = ARRAY_SIZE(ov5640_setting_QVGA_320_240), .max_fps = OV5640_30_FPS @@ -720,8 +720,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 640, .height = 480, }, - .htot = 1896, - .vblank_def = 600, + .htot = 1600, + .vblank_def = 520, .reg_data = ov5640_setting_VGA_640_480, .reg_data_size = ARRAY_SIZE(ov5640_setting_VGA_640_480), .max_fps = OV5640_60_FPS @@ -745,7 +745,7 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .height = 480, }, .htot = 1896, - .vblank_def = 504, + .vblank_def = 1206, .reg_data = ov5640_setting_NTSC_720_480, .reg_data_size = ARRAY_SIZE(ov5640_setting_NTSC_720_480), .max_fps = OV5640_30_FPS @@ -769,7 +769,7 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .height = 576, }, .htot = 1896, - .vblank_def = 408, + .vblank_def = 1110, .reg_data = ov5640_setting_PAL_720_576, .reg_data_size = ARRAY_SIZE(ov5640_setting_PAL_720_576), .max_fps = OV5640_30_FPS @@ -793,7 +793,7 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .height = 768, }, .htot = 1896, - .vblank_def = 312, + .vblank_def = 918, .reg_data = ov5640_setting_XGA_1024_768, .reg_data_size = ARRAY_SIZE(ov5640_setting_XGA_1024_768), .max_fps = OV5640_30_FPS @@ -816,8 +816,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 1280, .height = 720, }, - .htot = 1892, - .vblank_def = 20, + .htot = 1600, + .vblank_def = 560, .reg_data = ov5640_setting_720P_1280_720, .reg_data_size = ARRAY_SIZE(ov5640_setting_720P_1280_720), .max_fps = OV5640_30_FPS @@ -840,8 +840,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { .width = 1920, .height = 1080, }, - .htot = 2500, - .vblank_def = 40, + .htot = 2234, + .vblank_def = 24, .reg_data = ov5640_setting_1080P_1920_1080, .reg_data_size = ARRAY_SIZE(ov5640_setting_1080P_1920_1080), .max_fps = OV5640_30_FPS From patchwork Thu Feb 10 11:10:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541981 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1282C433F5 for ; Thu, 10 Feb 2022 11:09:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240578AbiBJLJS (ORCPT ); Thu, 10 Feb 2022 06:09:18 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240573AbiBJLJR (ORCPT ); Thu, 10 Feb 2022 06:09:17 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 938F1128 for ; Thu, 10 Feb 2022 03:09:18 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 521981C0005; Thu, 10 Feb 2022 11:09:14 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 16/23] media: ov5640: Implement init_cfg Date: Thu, 10 Feb 2022 12:10:01 +0100 Message-Id: <20220210111004.152859-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement the init_cfg pad operation to initialize the subdev state format to the default one. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index dd7ff1bb580f..8b90fab26d16 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -390,6 +390,18 @@ static inline bool ov5640_is_csi2(struct ov5640_dev *sensor) * over i2c. */ /* YUV422 UYVY VGA@30fps */ + +static const struct v4l2_mbus_framefmt ov5640_default_fmt = { + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .width = 640, + .height = 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB), + .quantization = V4L2_QUANTIZATION_FULL_RANGE, + .xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB), + .field = V4L2_FIELD_NONE, +}; + static const struct reg_value ov5640_init_setting[] = { {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0}, @@ -3367,6 +3379,16 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable) return ret; } +static int ov5640_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_mbus_framefmt *fmt = v4l2_subdev_get_try_format(sd, state, 0); + + *fmt = ov5640_default_fmt; + + return 0; +} + static const struct v4l2_subdev_core_ops ov5640_core_ops = { .s_power = ov5640_s_power, .log_status = v4l2_ctrl_subdev_log_status, @@ -3381,6 +3403,7 @@ static const struct v4l2_subdev_video_ops ov5640_video_ops = { }; static const struct v4l2_subdev_pad_ops ov5640_pad_ops = { + .init_cfg = ov5640_init_cfg, .enum_mbus_code = ov5640_enum_mbus_code, .get_fmt = ov5640_get_fmt, .set_fmt = ov5640_set_fmt, @@ -3439,7 +3462,6 @@ static int ov5640_probe(struct i2c_client *client) struct device *dev = &client->dev; struct fwnode_handle *endpoint; struct ov5640_dev *sensor; - struct v4l2_mbus_framefmt *fmt; u32 rotation; int ret; @@ -3453,15 +3475,7 @@ static int ov5640_probe(struct i2c_client *client) * default init sequence initialize sensor to * YUV422 UYVY VGA@30fps */ - fmt = &sensor->fmt; - fmt->code = MEDIA_BUS_FMT_UYVY8_2X8; - fmt->colorspace = V4L2_COLORSPACE_SRGB; - fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace); - fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; - fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace); - fmt->width = 640; - fmt->height = 480; - fmt->field = V4L2_FIELD_NONE; + sensor->fmt = ov5640_default_fmt; sensor->frame_interval.numerator = 1; sensor->frame_interval.denominator = ov5640_framerates[OV5640_30_FPS]; sensor->current_fr = OV5640_30_FPS; From patchwork Thu Feb 10 11:10:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541626 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F019EC433EF for ; Thu, 10 Feb 2022 11:09:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240581AbiBJLJY (ORCPT ); Thu, 10 Feb 2022 06:09:24 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240574AbiBJLJU (ORCPT ); Thu, 10 Feb 2022 06:09:20 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 356BAB71 for ; Thu, 10 Feb 2022 03:09:22 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 92B151C0010; Thu, 10 Feb 2022 11:09:17 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 17/23] media: ov5640: Implement get_selection Date: Thu, 10 Feb 2022 12:10:02 +0100 Message-Id: <20220210111004.152859-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement the get_selection pad operation for the OV5640 sensor driver. The supported targets report the sensor's native size, the active pixel array size and the analog crop rectangle from which the image is produced. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 8b90fab26d16..4ebb76d95849 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -35,6 +35,13 @@ #define OV5640_MIN_VBLANK 24 #define OV5640_MAX_VTS 1968 +#define OV5640_NATIVE_WIDTH 2624 +#define OV5640_NATIVE_HEIGHT 1964 +#define OV5640_PIXEL_ARRAY_TOP 14 +#define OV5640_PIXEL_ARRAY_LEFT 16 +#define OV5640_PIXEL_ARRAY_WIDTH 2592 +#define OV5640_PIXEL_ARRAY_HEIGHT 1944 + #define OV5640_DEFAULT_SLAVE_ID 0x3c #define OV5640_LINK_RATE_MAX 490000000U @@ -2693,6 +2700,43 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd, return ret; } +static int ov5640_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) +{ + struct ov5640_dev *sensor = to_ov5640_dev(sd); + const struct ov5640_mode_info *mode = sensor->current_mode; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: { + mutex_lock(&sensor->lock); + sel->r = mode->analog_crop; + mutex_unlock(&sensor->lock); + + return 0; + } + + case V4L2_SEL_TGT_NATIVE_SIZE: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = OV5640_NATIVE_WIDTH; + sel->r.height = OV5640_NATIVE_HEIGHT; + + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.top = OV5640_PIXEL_ARRAY_TOP; + sel->r.left = OV5640_PIXEL_ARRAY_LEFT; + sel->r.width = OV5640_PIXEL_ARRAY_WIDTH; + sel->r.height = OV5640_PIXEL_ARRAY_HEIGHT; + + return 0; + } + + return -EINVAL; +} + static int ov5640_set_framefmt(struct ov5640_dev *sensor, struct v4l2_mbus_framefmt *format) { @@ -3383,9 +3427,15 @@ static int ov5640_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *state) { struct v4l2_mbus_framefmt *fmt = v4l2_subdev_get_try_format(sd, state, 0); + struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, state, 0); *fmt = ov5640_default_fmt; + crop->left = OV5640_PIXEL_ARRAY_LEFT; + crop->top = OV5640_PIXEL_ARRAY_TOP; + crop->width = OV5640_PIXEL_ARRAY_WIDTH; + crop->height = OV5640_PIXEL_ARRAY_HEIGHT; + return 0; } @@ -3407,6 +3457,7 @@ static const struct v4l2_subdev_pad_ops ov5640_pad_ops = { .enum_mbus_code = ov5640_enum_mbus_code, .get_fmt = ov5640_get_fmt, .set_fmt = ov5640_set_fmt, + .get_selection = ov5640_get_selection, .enum_frame_size = ov5640_enum_frame_size, .enum_frame_interval = ov5640_enum_frame_interval, }; From patchwork Thu Feb 10 11:10:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541980 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EEB1C433FE for ; Thu, 10 Feb 2022 11:09:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240582AbiBJLJZ (ORCPT ); Thu, 10 Feb 2022 06:09:25 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240580AbiBJLJY (ORCPT ); Thu, 10 Feb 2022 06:09:24 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8FD6A128 for ; Thu, 10 Feb 2022 03:09:25 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 29D761C000E; Thu, 10 Feb 2022 11:09:21 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 18/23] media: ov5640: Limit frame_interval to DVP mode only Date: Thu, 10 Feb 2022 12:10:03 +0100 Message-Id: <20220210111004.152859-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org In MIPI mode the frame rate control is performed by adjusting the frame blankings and the s_frame_interval function is not used anymore. Only check for the per-mode supported frame rate in DVP mode and do not restrict MIPI mode. Disallow enum/s/g_frame_interval if the chip is used in MIPI mode. While at it re-indent one function which whose parameters were wrongly aligned. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 4ebb76d95849..6695bb2b99b7 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -1872,8 +1872,13 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, (mode->crop.width != width || mode->crop.height != height))) return NULL; - /* Check to see if the current mode exceeds the max frame rate */ - if (ov5640_framerates[fr] > ov5640_framerates[mode->max_fps]) + /* + * Check to see if the current mode exceeds the max frame rate. + * Only DVP mode uses the frame rate set by s_frame_interval, MIPI + * mode controls framerate by setting blankings. + */ + if (!ov5640_is_csi2(sensor) && + ov5640_framerates[fr] > ov5640_framerates[mode->max_fps]) return NULL; return mode; @@ -3288,15 +3293,17 @@ static int ov5640_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int ov5640_enum_frame_interval( - struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval_enum *fie) +static int ov5640_enum_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_interval_enum *fie) { struct ov5640_dev *sensor = to_ov5640_dev(sd); struct v4l2_fract tpf; int ret; + if (ov5640_is_csi2(sensor)) + return -EINVAL; + if (fie->pad != 0) return -EINVAL; if (fie->index >= OV5640_NUM_FRAMERATES) @@ -3319,6 +3326,9 @@ static int ov5640_g_frame_interval(struct v4l2_subdev *sd, { struct ov5640_dev *sensor = to_ov5640_dev(sd); + if (ov5640_is_csi2(sensor)) + return -EINVAL; + mutex_lock(&sensor->lock); fi->interval = sensor->frame_interval; mutex_unlock(&sensor->lock); @@ -3333,6 +3343,9 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd, const struct ov5640_mode_info *mode; int frame_rate, ret = 0; + if (ov5640_is_csi2(sensor)) + return -EINVAL; + if (fi->pad != 0) return -EINVAL; From patchwork Thu Feb 10 11:10:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E16CC433F5 for ; Thu, 10 Feb 2022 11:09:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234367AbiBJLJa (ORCPT ); Thu, 10 Feb 2022 06:09:30 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240580AbiBJLJ2 (ORCPT ); Thu, 10 Feb 2022 06:09:28 -0500 Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F47FB74 for ; Thu, 10 Feb 2022 03:09:29 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 9BA121C0004; Thu, 10 Feb 2022 11:09:24 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 19/23] media: ov5640: Register device properties Date: Thu, 10 Feb 2022 12:10:04 +0100 Message-Id: <20220210111004.152859-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Parse the device properties and register the rotation and orientation V4L2 controls using v4l2_ctrl_new_fwnode_properties(). Remove the open-coded parsing of the rotation property and assume the DTS is correct is providing either <0> or <180> as possible rotations. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 6695bb2b99b7..aecc8912099a 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -3182,6 +3182,7 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops; struct ov5640_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; + struct v4l2_fwnode_device_properties props; unsigned int max_vblank; unsigned int hblank; int ret; @@ -3258,6 +3259,17 @@ static int ov5640_init_controls(struct ov5640_dev *sensor) goto free_ctrls; } + ret = v4l2_fwnode_device_parse(&sensor->i2c_client->dev, &props); + if (ret) + goto free_ctrls; + + if (props.rotation == 180) + sensor->upside_down = true; + + ret = v4l2_ctrl_new_fwnode_properties(hdl, ops, &props); + if (ret) + goto free_ctrls; + ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; @@ -3526,7 +3538,6 @@ static int ov5640_probe(struct i2c_client *client) struct device *dev = &client->dev; struct fwnode_handle *endpoint; struct ov5640_dev *sensor; - u32 rotation; int ret; sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); @@ -3549,22 +3560,6 @@ static int ov5640_probe(struct i2c_client *client) sensor->ae_target = 52; - /* optional indication of physical rotation of sensor */ - ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation", - &rotation); - if (!ret) { - switch (rotation) { - case 180: - sensor->upside_down = true; - fallthrough; - case 0: - break; - default: - dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n", - rotation); - } - } - endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); if (!endpoint) { From patchwork Thu Feb 10 11:10:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4576C433EF for ; Thu, 10 Feb 2022 11:09:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240589AbiBJLJy (ORCPT ); Thu, 10 Feb 2022 06:09:54 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240580AbiBJLJx (ORCPT ); Thu, 10 Feb 2022 06:09:53 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F722128 for ; Thu, 10 Feb 2022 03:09:54 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 343F224000A; Thu, 10 Feb 2022 11:09:48 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 20/23] media: ov5640: Add RGB565_1X16 format Date: Thu, 10 Feb 2022 12:10:41 +0100 Message-Id: <20220210111044.152904-1-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The driver already supports the 2X8_[LE|BE] variants of RGB565 formats. As for CSI-2 the 2X8 variants do not apply, add RGB565_1X16 variant with little-endian ordering of components as required by the CSI-2 specifications. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5640.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index aecc8912099a..3a21f4648acf 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -220,6 +220,10 @@ static const struct ov5640_pixfmt { .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .colorspace = V4L2_COLORSPACE_SRGB, .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_RGB565_1X16, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, }, { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .colorspace = V4L2_COLORSPACE_SRGB, @@ -2763,6 +2767,7 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor, mux = OV5640_FMT_MUX_YUV422; break; case MEDIA_BUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_1X16: /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */ fmt = 0x6F; mux = OV5640_FMT_MUX_RGB; From patchwork Thu Feb 10 11:10:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541624 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 995A5C433EF for ; Thu, 10 Feb 2022 11:10:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240591AbiBJLJ5 (ORCPT ); Thu, 10 Feb 2022 06:09:57 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43594 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240580AbiBJLJ4 (ORCPT ); Thu, 10 Feb 2022 06:09:56 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 178E4128 for ; Thu, 10 Feb 2022 03:09:57 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id A021D240011; Thu, 10 Feb 2022 11:09:53 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 21/23] media: ov5640: Add RGB888/BGR888 formats Date: Thu, 10 Feb 2022 12:10:42 +0100 Message-Id: <20220210111044.152904-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support for RGB888/BGR888 image formats. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 3a21f4648acf..f894570ac53c 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -224,6 +224,14 @@ static const struct ov5640_pixfmt { .code = MEDIA_BUS_FMT_RGB565_1X16, .colorspace = V4L2_COLORSPACE_SRGB, .bpp = 16, + }, { + .code = MEDIA_BUS_FMT_RGB888_1X24, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 24, + }, { + .code = MEDIA_BUS_FMT_BGR888_1X24, + .colorspace = V4L2_COLORSPACE_SRGB, + .bpp = 16, }, { .code = MEDIA_BUS_FMT_SBGGR8_1X8, .colorspace = V4L2_COLORSPACE_SRGB, @@ -2777,6 +2785,16 @@ static int ov5640_set_framefmt(struct ov5640_dev *sensor, fmt = 0x61; mux = OV5640_FMT_MUX_RGB; break; + case MEDIA_BUS_FMT_RGB888_1X24: + /* RGB888: BGR */ + fmt = 0x22; + mux = OV5640_FMT_MUX_RGB; + break; + case MEDIA_BUS_FMT_BGR888_1X24: + /* BGR888: RGB */ + fmt = 0x23; + mux = OV5640_FMT_MUX_RGB; + break; case MEDIA_BUS_FMT_JPEG_1X8: /* YUV422, YUYV */ fmt = 0x30; From patchwork Thu Feb 10 11:10:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541978 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14572C433EF for ; Thu, 10 Feb 2022 11:10:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240613AbiBJLKB (ORCPT ); Thu, 10 Feb 2022 06:10:01 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240602AbiBJLKA (ORCPT ); Thu, 10 Feb 2022 06:10:00 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6872128 for ; Thu, 10 Feb 2022 03:10:01 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id ED261240013; Thu, 10 Feb 2022 11:09:56 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 22/23] media: ov5640: Restrict sizes to mbus code Date: Thu, 10 Feb 2022 12:10:43 +0100 Message-Id: <20220210111044.152904-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ov5640 driver supports different sizes for different mbus_codes. In particular: - 8bpp modes: high resolution sizes (>= 1280x720) - 16bpp modes: all sizes - 24bpp modes: low resolutions sizes (< 1280x720) Restrict the frame sizes enumerations to the above constraints. While at it, make sure the fse->mbus_code parameter is valid, and return -EINVAL if it's not. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index f894570ac53c..81bf547a923e 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -3315,14 +3315,28 @@ static int ov5640_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { + u32 bpp = ov5640_code_to_bpp(fse->code); + unsigned int index = fse->index; + if (fse->pad != 0) return -EINVAL; - if (fse->index >= OV5640_NUM_MODES) + if (!bpp) + return -EINVAL; + + /* Only low-resolution modes are supported for 24bpp modes. */ + if (bpp == 24 && index >= OV5640_MODE_720P_1280_720) + return -EINVAL; + + /* Only high-resolutions modes are supported for 8bpp formats. */ + if (bpp == 8) + index += OV5640_MODE_720P_1280_720; + + if (index >= OV5640_NUM_MODES) return -EINVAL; - fse->min_width = ov5640_mode_data[fse->index].crop.width; + fse->min_width = ov5640_mode_data[index].crop.width; fse->max_width = fse->min_width; - fse->min_height = ov5640_mode_data[fse->index].crop.height; + fse->min_height = ov5640_mode_data[index].crop.height; fse->max_height = fse->min_height; return 0; From patchwork Thu Feb 10 11:10:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 541623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BF80C433EF for ; Thu, 10 Feb 2022 11:10:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240629AbiBJLKF (ORCPT ); Thu, 10 Feb 2022 06:10:05 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:43680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240620AbiBJLKD (ORCPT ); Thu, 10 Feb 2022 06:10:03 -0500 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C1D7B74 for ; Thu, 10 Feb 2022 03:10:04 -0800 (PST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6120424000B; Thu, 10 Feb 2022 11:10:00 +0000 (UTC) From: Jacopo Mondi To: slongerbeam@gmail.com Cc: laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, hverkuil-cisco@xs4all.nl, mirela.rabulea@nxp.com, xavier.roumegue@oss.nxp.com, tomi.valkeinen@ideasonboard.com, hugues.fruchet@st.com, prabhakar.mahadev-lad.rj@bp.renesas.com, aford173@gmail.com, festevam@gmail.com, eugen.hristev@microchip.com, jbrunet@baylibre.com, mchehab@kernel.org, linux-media@vger.kernel.org, Jacopo Mondi Subject: [PATCH v2 23/23] media: ov5640: Adjust format to bpp in s_fmt Date: Thu, 10 Feb 2022 12:10:44 +0100 Message-Id: <20220210111044.152904-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.35.0 In-Reply-To: <20220210110458.152494-1-jacopo@jmondi.org> References: <20220210110458.152494-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ov5640 driver supports different sizes for different mbus_codes. In particular: - 8bpp modes: high resolution sizes (>= 1280x720) - 16bpp modes: all sizes - 24bpp modes: low resolutions sizes (< 1280x720) Adjust the image sizes according to the above constraints. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index 81bf547a923e..465b09176169 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -2563,6 +2563,7 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, enum ov5640_frame_rate fr, const struct ov5640_mode_info **new_mode) { + unsigned int bpp = ov5640_code_to_bpp(fmt->code); struct ov5640_dev *sensor = to_ov5640_dev(sd); const struct ov5640_mode_info *mode; int i; @@ -2570,6 +2571,17 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd, mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true); if (!mode) return -EINVAL; + + /* + * Adjust mode according to bpp: + * - 8bpp modes work for resolution >= 1280x720 + * - 24bpp modes work resolution < 1280x720 + */ + if (bpp == 8 && mode->crop.width < 1280) + mode = &ov5640_mode_data[OV5640_MODE_720P_1280_720]; + else if (bpp == 24 && mode->crop.width > 1024) + mode = &ov5640_mode_data[OV5640_MODE_XGA_1024_768]; + fmt->width = mode->crop.width; fmt->height = mode->crop.height;