From patchwork Wed Oct 5 19:06:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 612692 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 4758DC4332F for ; Wed, 5 Oct 2022 19:07:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230469AbiJETHk (ORCPT ); Wed, 5 Oct 2022 15:07:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231503AbiJETGp (ORCPT ); Wed, 5 Oct 2022 15:06:45 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDB5678BE6 for ; Wed, 5 Oct 2022 12:06:43 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id D50F4FF808; Wed, 5 Oct 2022 19:06:40 +0000 (UTC) From: Jacopo Mondi To: =?utf-8?q?Krzysztof_Ha=C5=82asa?= , Mauro Carvalho Chehab , Sakari Ailus , Laurent Pinchart Cc: Jacopo Mondi , linux-media@vger.kernel.org Subject: [PATCH 02/10] media: ar0521: Add V4L2_CID_ANALOG_GAIN Date: Wed, 5 Oct 2022 21:06:05 +0200 Message-Id: <20221005190613.394277-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221005190613.394277-1-jacopo@jmondi.org> References: <20221005190613.394277-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support for V4L2_CID_ANALOG_GAIN. The control programs the global gain register which applies to all color channels. As both the global digital and analog gains are controlled through a single register, in order not to overwrite the configured digital gain we need to read the current register value before modifying it. Implement a function to read register values and use it before applying the new analog gain. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ar0521.c | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index 89f3c01f18ce..581f5e42994d 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -5,6 +5,8 @@ * Written by Krzysztof HaƂasa */ +#include + #include #include #include @@ -35,6 +37,11 @@ #define AR0521_HEIGHT_BLANKING_MIN 38u /* must be even */ #define AR0521_TOTAL_WIDTH_MIN 2968u +#define AR0521_ANA_GAIN_MIN 0x00 +#define AR0521_ANA_GAIN_MAX 0x3f +#define AR0521_ANA_GAIN_STEP 0x01 +#define AR0521_ANA_GAIN_DEFAULT 0x00 + /* AR0521 registers */ #define AR0521_REG_VT_PIX_CLK_DIV 0x0300 #define AR0521_REG_FRAME_LENGTH_LINES 0x0340 @@ -55,6 +62,7 @@ #define AR0521_REG_RED_GAIN 0x305A #define AR0521_REG_GREEN2_GAIN 0x305C #define AR0521_REG_GLOBAL_GAIN 0x305E +#define AR0521_REG_GLOBAL_GAIN_ANA_MASK 0x3f #define AR0521_REG_HISPI_TEST_MODE 0x3066 #define AR0521_REG_HISPI_TEST_MODE_LP11 0x0004 @@ -77,6 +85,7 @@ static const char * const ar0521_supply_names[] = { struct ar0521_ctrls { struct v4l2_ctrl_handler handler; + struct v4l2_ctrl *ana_gain; struct { struct v4l2_ctrl *gain; struct v4l2_ctrl *red_balance; @@ -167,6 +176,36 @@ static int ar0521_write_reg(struct ar0521_dev *sensor, u16 reg, u16 val) return ar0521_write_regs(sensor, buf, 2); } +static int ar0521_read_reg(struct ar0521_dev *sensor, u16 reg, u16 *val) +{ + struct i2c_client *client = sensor->i2c_client; + unsigned char buf[2]; + struct i2c_msg msg; + int ret; + + msg.addr = client->addr; + msg.flags = client->flags; + msg.len = sizeof(u16); + msg.buf = buf; + put_unaligned_be16(reg, buf); + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + return ret; + + msg.len = sizeof(u16); + msg.flags = client->flags | I2C_M_RD; + msg.buf = buf; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret < 0) + return ret; + + *val = get_unaligned_be16(buf); + + return 0; +} + static int ar0521_set_geometry(struct ar0521_dev *sensor) { /* All dimensions are unsigned 12-bit integers */ @@ -187,6 +226,21 @@ static int ar0521_set_geometry(struct ar0521_dev *sensor) return ar0521_write_regs(sensor, regs, ARRAY_SIZE(regs)); } +static int ar0521_set_analog_gain(struct ar0521_dev *sensor) +{ + u16 global_gain; + int ret; + + ret = ar0521_read_reg(sensor, AR0521_REG_GLOBAL_GAIN, &global_gain); + if (ret) + return ret; + + global_gain &= ~AR0521_REG_GLOBAL_GAIN_ANA_MASK; + global_gain |= sensor->ctrls.ana_gain->val & AR0521_REG_GLOBAL_GAIN_ANA_MASK; + + return ar0521_write_reg(sensor, AR0521_REG_GLOBAL_GAIN, global_gain); +} + static int ar0521_set_gains(struct ar0521_dev *sensor) { int green = sensor->ctrls.gain->val; @@ -456,6 +510,9 @@ static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_VBLANK: ret = ar0521_set_geometry(sensor); break; + case V4L2_CID_ANALOGUE_GAIN: + ret = ar0521_set_analog_gain(sensor); + break; case V4L2_CID_GAIN: case V4L2_CID_RED_BALANCE: case V4L2_CID_BLUE_BALANCE: @@ -499,6 +556,13 @@ static int ar0521_init_controls(struct ar0521_dev *sensor) /* We can use our own mutex for the ctrl lock */ hdl->lock = &sensor->lock; + /* Analog gain */ + ctrls->ana_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, + AR0521_ANA_GAIN_MIN, + AR0521_ANA_GAIN_MAX, + AR0521_ANA_GAIN_STEP, + AR0521_ANA_GAIN_DEFAULT); + /* Manual gain */ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 511, 1, 0); ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, From patchwork Wed Oct 5 19:06:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 612697 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 9C49BC433FE for ; Wed, 5 Oct 2022 19:06:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231363AbiJETG5 (ORCPT ); Wed, 5 Oct 2022 15:06:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50506 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231206AbiJETG4 (ORCPT ); Wed, 5 Oct 2022 15:06:56 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B55037FFA4 for ; Wed, 5 Oct 2022 12:06:48 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 0A979FF80B; Wed, 5 Oct 2022 19:06:42 +0000 (UTC) From: Jacopo Mondi To: =?utf-8?q?Krzysztof_Ha=C5=82asa?= , Mauro Carvalho Chehab , Sakari Ailus , Laurent Pinchart Cc: Jacopo Mondi , linux-media@vger.kernel.org Subject: [PATCH 03/10] media: ar0521: Set maximum resolution to 2592x1944 Date: Wed, 5 Oct 2022 21:06:06 +0200 Message-Id: <20221005190613.394277-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221005190613.394277-1-jacopo@jmondi.org> References: <20221005190613.394277-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Change the largest visibile resolution to 2592x1944, which corresponds to the active pixel array area size. Take into account the horizontal and vertical limits when programming the visible sizes to skip dummy/inactive pixels. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ar0521.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index 581f5e42994d..2b19ba898ce8 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -28,10 +28,17 @@ #define AR0521_PIXEL_CLOCK_MIN (168 * 1000 * 1000) #define AR0521_PIXEL_CLOCK_MAX (414 * 1000 * 1000) +#define AR0521_NATIVE_WIDTH 2604u +#define AR0521_NATIVE_HEIGHT 1964u +#define AR0521_MIN_X_ADDR_START 4u +#define AR0521_MIN_Y_ADDR_START 4u +#define AR0521_MAX_X_ADDR_END 2603u +#define AR0521_MAX_Y_ADDR_END 1963u + #define AR0521_WIDTH_MIN 8u -#define AR0521_WIDTH_MAX 2608u +#define AR0521_WIDTH_MAX 2592u #define AR0521_HEIGHT_MIN 8u -#define AR0521_HEIGHT_MAX 1958u +#define AR0521_HEIGHT_MAX 1944u #define AR0521_WIDTH_BLANKING_MIN 572u #define AR0521_HEIGHT_BLANKING_MIN 38u /* must be even */ @@ -208,13 +215,17 @@ static int ar0521_read_reg(struct ar0521_dev *sensor, u16 reg, u16 *val) static int ar0521_set_geometry(struct ar0521_dev *sensor) { + /* Center the image in the visible ouput window. */ + u16 x = clamp((AR0521_WIDTH_MAX - sensor->fmt.width) / 2, + AR0521_MIN_X_ADDR_START, AR0521_MAX_X_ADDR_END); + u16 y = clamp(((AR0521_HEIGHT_MAX - sensor->fmt.height) / 2) & ~1, + AR0521_MIN_Y_ADDR_START, AR0521_MAX_Y_ADDR_END); + /* All dimensions are unsigned 12-bit integers */ - u16 x = (AR0521_WIDTH_MAX - sensor->fmt.width) / 2; - u16 y = ((AR0521_HEIGHT_MAX - sensor->fmt.height) / 2) & ~1; __be16 regs[] = { be(AR0521_REG_FRAME_LENGTH_LINES), - be(sensor->total_height), - be(sensor->total_width), + be(sensor->fmt.height + sensor->ctrls.vblank->val), + be(sensor->fmt.width + sensor->ctrls.hblank->val), be(x), be(y), be(x + sensor->fmt.width - 1), From patchwork Wed Oct 5 19:06:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 612696 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 C001AC43217 for ; Wed, 5 Oct 2022 19:07:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231325AbiJETG7 (ORCPT ); Wed, 5 Oct 2022 15:06:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231354AbiJETG5 (ORCPT ); Wed, 5 Oct 2022 15:06:57 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF9697FFB3 for ; Wed, 5 Oct 2022 12:06:50 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 659DFFF804; Wed, 5 Oct 2022 19:06:47 +0000 (UTC) From: Jacopo Mondi To: =?utf-8?q?Krzysztof_Ha=C5=82asa?= , Mauro Carvalho Chehab , Sakari Ailus , Laurent Pinchart Cc: Jacopo Mondi , linux-media@vger.kernel.org Subject: [PATCH 05/10] media: ar0521: Add LINK_FREQ control Date: Wed, 5 Oct 2022 21:06:08 +0200 Message-Id: <20221005190613.394277-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221005190613.394277-1-jacopo@jmondi.org> References: <20221005190613.394277-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support for V4L2_CID_LINK_FREQ which currently reports a single hard-coded frequency which depends on the fixed pixel clock. This will change in the next patches where the pixel rate will be computed from the desired link_frequency. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ar0521.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index 21649aecf442..c5410b091654 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -90,6 +90,10 @@ static const char * const ar0521_supply_names[] = { "vaa", /* Analog (2.7V) supply */ }; +static const s64 ar0521_link_frequencies[] = { + 184000000, +}; + struct ar0521_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *ana_gain; @@ -104,6 +108,7 @@ struct ar0521_ctrls { }; struct v4l2_ctrl *pixrate; struct v4l2_ctrl *exposure; + struct v4l2_ctrl *link_freq; struct v4l2_ctrl *test_pattern; }; @@ -655,6 +660,10 @@ static int ar0521_init_controls(struct ar0521_dev *sensor) ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, 65535, 1, 360); + ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ, + ARRAY_SIZE(ar0521_link_frequencies) - 1, + 0, ar0521_link_frequencies); + ctrls->test_pattern = v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN, ARRAY_SIZE(test_pattern_menu) - 1, From patchwork Wed Oct 5 19:06:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 612695 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 5EEEAC433F5 for ; Wed, 5 Oct 2022 19:07:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231410AbiJETHB (ORCPT ); Wed, 5 Oct 2022 15:07:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231371AbiJETG5 (ORCPT ); Wed, 5 Oct 2022 15:06:57 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76FA67FE69 for ; Wed, 5 Oct 2022 12:06:56 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 84587FF808; Wed, 5 Oct 2022 19:06:51 +0000 (UTC) From: Jacopo Mondi To: =?utf-8?q?Krzysztof_Ha=C5=82asa?= , Mauro Carvalho Chehab , Sakari Ailus , Laurent Pinchart Cc: Jacopo Mondi , linux-media@vger.kernel.org Subject: [PATCH 07/10] media: ar0521: Adjust exposure and blankings limits Date: Wed, 5 Oct 2022 21:06:10 +0200 Message-Id: <20221005190613.394277-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221005190613.394277-1-jacopo@jmondi.org> References: <20221005190613.394277-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Adjust the control limits for V4L2_CID_VBLANK, V4L2_CID_HBLANK and V4L2_CID_EXPOSURE when a new format is applied to the sensor. Also update the exposure control when a new blanking value is applied. Also change the controls initialization to use valid values for the default format. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ar0521.c | 77 ++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index b1580c99f5e3..26bb1b8f7453 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -42,7 +42,8 @@ #define AR0521_WIDTH_BLANKING_MIN 572u #define AR0521_HEIGHT_BLANKING_MIN 38u /* must be even */ -#define AR0521_TOTAL_WIDTH_MIN 2968u +#define AR0521_TOTAL_HEIGHT_MAX 2464u /* max value of y_addr_end reg */ +#define AR0521_TOTAL_WIDTH_MAX 3280u /* max value of x_addr_end reg */ #define AR0521_ANA_GAIN_MIN 0x00 #define AR0521_ANA_GAIN_MAX 0x3f @@ -131,8 +132,6 @@ struct ar0521_dev { struct v4l2_mbus_framefmt fmt; struct ar0521_ctrls ctrls; unsigned int lane_count; - u16 total_width; - u16 total_height; struct { u16 pre; u16 mult; @@ -544,7 +543,8 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ar0521_dev *sensor = to_ar0521_dev(sd); - int ret = 0; + int exposure_max, exposure_val; + int max_vblank, max_hblank; ar0521_adj_fmt(&format->format); @@ -555,13 +555,44 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd, fmt = v4l2_subdev_get_try_format(sd, sd_state, 0 /* pad */); *fmt = format->format; - } else { - sensor->fmt = format->format; - ar0521_calc_mode(sensor); + + mutex_unlock(&sensor->lock); + + return 0; } + sensor->fmt = format->format; + ar0521_calc_mode(sensor); + + /* + * Update the exposure and blankings limits. Blankings are also reset + * to the minimum. + */ + max_hblank = AR0521_TOTAL_WIDTH_MAX - sensor->fmt.width; + __v4l2_ctrl_modify_range(sensor->ctrls.hblank, + sensor->ctrls.hblank->minimum, + max_hblank, sensor->ctrls.hblank->step, + sensor->ctrls.hblank->minimum); + __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, sensor->ctrls.hblank->minimum); + + max_vblank = AR0521_TOTAL_HEIGHT_MAX - sensor->fmt.height; + __v4l2_ctrl_modify_range(sensor->ctrls.vblank, + sensor->ctrls.vblank->minimum, + max_vblank, sensor->ctrls.vblank->step, + sensor->ctrls.vblank->minimum); + __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, sensor->ctrls.vblank->minimum); + + exposure_max = sensor->fmt.height + AR0521_HEIGHT_BLANKING_MIN - 4; + exposure_val = min(sensor->ctrls.exposure->val, exposure_max); + __v4l2_ctrl_modify_range(sensor->ctrls.exposure, + sensor->ctrls.exposure->minimum, + exposure_max, sensor->ctrls.exposure->step, + exposure_val); + __v4l2_ctrl_s_ctrl(sensor->ctrls.exposure, exposure_val); + mutex_unlock(&sensor->lock); - return ret; + + return 0; } static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl) @@ -573,15 +604,13 @@ static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl) /* v4l2_ctrl_lock() locks our own mutex */ switch (ctrl->id) { - case V4L2_CID_HBLANK: case V4L2_CID_VBLANK: - sensor->total_width = sensor->fmt.width + - sensor->ctrls.hblank->val; - sensor->total_height = sensor->fmt.width + - sensor->ctrls.vblank->val; - break; - default: - ret = -EINVAL; + int exp_max = sensor->fmt.height + ctrl->val - 4; + int exp_val = min(sensor->ctrls.exposure->val, exp_max); + __v4l2_ctrl_modify_range(sensor->ctrls.exposure, + sensor->ctrls.exposure->minimum, + exp_max, sensor->ctrls.exposure->step, + exp_val); break; } @@ -633,6 +662,7 @@ static int ar0521_init_controls(struct ar0521_dev *sensor) const struct v4l2_ctrl_ops *ops = &ar0521_ctrl_ops; struct ar0521_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; + int max_vblank, max_hblank, exposure_max; int ret; v4l2_ctrl_handler_init(hdl, 32); @@ -655,11 +685,17 @@ static int ar0521_init_controls(struct ar0521_dev *sensor) -512, 511, 1, 0); v4l2_ctrl_cluster(3, &ctrls->gain); + /* Initialize blanking limits using the default 2592x1944 format. */ + max_hblank = AR0521_TOTAL_WIDTH_MAX - AR0521_WIDTH_MAX; ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, - AR0521_WIDTH_BLANKING_MIN, 4094, 1, + AR0521_WIDTH_BLANKING_MIN, + max_hblank, 1, AR0521_WIDTH_BLANKING_MIN); + + max_vblank = AR0521_TOTAL_HEIGHT_MAX - AR0521_HEIGHT_MAX; ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, - AR0521_HEIGHT_BLANKING_MIN, 4094, 2, + AR0521_HEIGHT_BLANKING_MIN, + max_vblank, 2, AR0521_HEIGHT_BLANKING_MIN); v4l2_ctrl_cluster(2, &ctrls->hblank); @@ -669,9 +705,10 @@ static int ar0521_init_controls(struct ar0521_dev *sensor) AR0521_PIXEL_CLOCK_MAX, 1, AR0521_PIXEL_CLOCK_RATE); - /* Manual exposure time */ + /* Manual exposure time: max exposure time = visible + blank - 4 */ + exposure_max = AR0521_HEIGHT_MAX + AR0521_HEIGHT_BLANKING_MIN - 4; ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, - 65535, 1, 360); + exposure_max, 1, 360); ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ, ARRAY_SIZE(ar0521_link_frequencies) - 1, From patchwork Wed Oct 5 19:06:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 612694 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 6A8D2C433FE for ; Wed, 5 Oct 2022 19:07:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231407AbiJETHD (ORCPT ); Wed, 5 Oct 2022 15:07:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231411AbiJETHB (ORCPT ); Wed, 5 Oct 2022 15:07:01 -0400 Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DF4478BE6 for ; Wed, 5 Oct 2022 12:07:00 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id C9DB2FF80C; Wed, 5 Oct 2022 19:06:55 +0000 (UTC) From: Jacopo Mondi To: =?utf-8?q?Krzysztof_Ha=C5=82asa?= , Mauro Carvalho Chehab , Sakari Ailus , Laurent Pinchart Cc: Jacopo Mondi , linux-media@vger.kernel.org Subject: [PATCH 09/10] media: ar0521: Rework startup sequence Date: Wed, 5 Oct 2022 21:06:12 +0200 Message-Id: <20221005190613.394277-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221005190613.394277-1-jacopo@jmondi.org> References: <20221005190613.394277-1-jacopo@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ar0521_write_mode() function explicitly programs the exposure time register and the test pattern register, which are now setup by the call to __v4l2_ctrl_handler_setup() in ar0521_set_stream(). Removing those register writes from ar0521_write_mode() reduces the function to two operations: geometry configuration and pll configuration. Move those operations in the ar0521_set_stream() caller and remove ar0521_write_mode(). However maintain the ar0521_calc_pll() function separated as it is used during pad format configuration to update the PIXEL_RATE control value. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ar0521.c | 50 ++++++++++++-------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) -- 2.37.3 diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index d46a51332964..670fa33acc6f 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -329,7 +329,7 @@ static u32 calc_pll(struct ar0521_dev *sensor, u32 freq, u16 *pre_ptr, u16 *mult return pll; } -static void ar0521_calc_mode(struct ar0521_dev *sensor) +static void ar0521_calc_pll(struct ar0521_dev *sensor) { unsigned int pixel_clock; unsigned int link_freq; @@ -403,7 +403,7 @@ static void ar0521_calc_mode(struct ar0521_dev *sensor) sensor->pll.mult = sensor->pll.mult2 = mult; } -static int ar0521_write_mode(struct ar0521_dev *sensor) +static int ar0521_pll_config(struct ar0521_dev *sensor) { __be16 pll_regs[] = { be(AR0521_REG_VT_PIX_CLK_DIV), @@ -414,36 +414,9 @@ static int ar0521_write_mode(struct ar0521_dev *sensor) /* 0x308 */ be(sensor->pll.vt_pix * 2), /* op_pix_clk_div = 2 * vt_pix_clk_div */ /* 0x30A */ be(1) /* op_sys_clk_div */ }; - int ret; - - /* Stop streaming for just a moment */ - ret = ar0521_write_reg(sensor, AR0521_REG_RESET, - AR0521_REG_RESET_DEFAULTS); - if (ret) - return ret; - - ret = ar0521_set_geometry(sensor); - if (ret) - return ret; - - ret = ar0521_write_regs(sensor, pll_regs, ARRAY_SIZE(pll_regs)); - if (ret) - return ret; - - ret = ar0521_write_reg(sensor, AR0521_REG_COARSE_INTEGRATION_TIME, - sensor->ctrls.exposure->val); - if (ret) - return ret; - - ret = ar0521_write_reg(sensor, AR0521_REG_RESET, - AR0521_REG_RESET_DEFAULTS | - AR0521_REG_RESET_STREAM); - if (ret) - return ret; - ret = ar0521_write_reg(sensor, AR0521_REG_TEST_PATTERN_MODE, - sensor->ctrls.test_pattern->val); - return ret; + ar0521_calc_pll(sensor); + return ar0521_write_regs(sensor, pll_regs, ARRAY_SIZE(pll_regs)); } static int ar0521_set_stream(struct ar0521_dev *sensor, bool on) @@ -455,8 +428,17 @@ static int ar0521_set_stream(struct ar0521_dev *sensor, bool on) if (ret < 0) return ret; - ar0521_calc_mode(sensor); - ret = ar0521_write_mode(sensor); + /* Stop streaming for just a moment */ + ret = ar0521_write_reg(sensor, AR0521_REG_RESET, + AR0521_REG_RESET_DEFAULTS); + if (ret) + return ret; + + ret = ar0521_set_geometry(sensor); + if (ret) + return ret; + + ret = ar0521_pll_config(sensor); if (ret) goto err; @@ -562,7 +544,7 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd, } sensor->fmt = format->format; - ar0521_calc_mode(sensor); + ar0521_calc_pll(sensor); /* * Update the exposure and blankings limits. Blankings are also reset