From patchwork Thu Aug 3 09:33:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339585 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 4EF39C41513 for ; Thu, 3 Aug 2023 09:34:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235054AbjHCJew (ORCPT ); Thu, 3 Aug 2023 05:34:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233358AbjHCJes (ORCPT ); Thu, 3 Aug 2023 05:34:48 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 414E530F9 for ; Thu, 3 Aug 2023 02:33:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055237; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tgUtdvWha1GhX10EvDPeO7wqvqtMO+kIFZkDIPabP4Y=; b=EQxvhYLVgCK+7vdT+FKmS+uXkMCAfv7YHswJJCdOoeGQ/BGTY/Ozj+3ynNaSIzjKtDiZKk xxHwJOiEj5UIudrjSnkFsszI7qQkm7y4MadHbWFRgFU8mqWUfL28KkDSaZKWSm2sxycJyY v+sII+GUnPZLQX0tdAZMIFTDgYsaoSU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-206-IVWEKXcIOYCN4F2Q_xwQEQ-1; Thu, 03 Aug 2023 05:33:53 -0400 X-MC-Unique: IVWEKXcIOYCN4F2Q_xwQEQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 10660805AF6; Thu, 3 Aug 2023 09:33:52 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9F5C42166B25; Thu, 3 Aug 2023 09:33:50 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 01/32] media: ov2680: Remove auto-gain and auto-exposure controls Date: Thu, 3 Aug 2023 11:33:16 +0200 Message-ID: <20230803093348.15679-2-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Quoting the OV2680 datasheet: "3.2 exposure and gain control In the OV2680, the exposure time and gain are set manually from an external controller. The OV2680 supports manual gain and exposure control only for normal applications, no auto mode." And indeed testing with the atomisp_ov2680 fork of ov2680.c has shown that auto-exposure and auto-gain do not work. Note that the code setting the auto-exposure flag was broken, callers of ov2680_exposure_set() were directly passing !!ctrls->auto_exp->val as "bool auto_exp" value, but ctrls->auto_exp is a menu control with: enum v4l2_exposure_auto_type { V4L2_EXPOSURE_AUTO = 0, V4L2_EXPOSURE_MANUAL = 1, ... So instead of passing !!ctrls->auto_exp->val they should have been passing ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO, iow the passed value was inverted of what it should have been. Also remove ov2680_g_volatile_ctrl() since without auto support the gain and exposure controls are not volatile. This also fixes the control values not being properly applied in ov2680_mode_set(). The 800x600 mode register-list also sets gain, exposure and vflip overriding the last set ctrl values. ov2680_mode_set() does call ov2680_gain_set() and ov2680_exposure_set() but did this before writing the mode register-list, so these values would still be overridden by the mode register-list. Add a v4l2_ctrl_handler_setup() call after writing the mode register-list to restore all ctrl values. Also remove the ctrls->gain->is_new check from ov2680_gain_set() so that the gain always gets restored properly. Last since ov2680_mode_set() now calls v4l2_ctrl_handler_setup(), remove the v4l2_ctrl_handler_setup() call after ov2680_mode_restore() since ov2680_mode_restore() calls ov2680_mode_set(). Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Reviewed-by: Daniel Scally Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 163 ++++--------------------------------- 1 file changed, 18 insertions(+), 145 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 0541b7c8e77b..3a737a1607a4 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -85,15 +85,8 @@ struct ov2680_mode_info { struct ov2680_ctrls { struct v4l2_ctrl_handler handler; - struct { - struct v4l2_ctrl *auto_exp; - struct v4l2_ctrl *exposure; - }; - struct { - struct v4l2_ctrl *auto_gain; - struct v4l2_ctrl *gain; - }; - + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; struct v4l2_ctrl *hflip; struct v4l2_ctrl *vflip; struct v4l2_ctrl *test_pattern; @@ -143,6 +136,7 @@ static const struct reg_value ov2680_setting_30fps_QUXGA_800_600[] = { {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, + {0x3503, 0x03}, }; static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { @@ -405,69 +399,15 @@ static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) return 0; } -static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain) +static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 gain; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), - auto_gain ? 0 : BIT(1)); - if (ret < 0) - return ret; - - if (auto_gain || !ctrls->gain->is_new) - return 0; - - gain = ctrls->gain->val; - - ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); - - return 0; + return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); } -static int ov2680_gain_get(struct ov2680_dev *sensor) +static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) { - u32 gain; - int ret; - - ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain); - if (ret) - return ret; - - return gain; -} - -static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp) -{ - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 exp; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0), - auto_exp ? 0 : BIT(0)); - if (ret < 0) - return ret; - - if (auto_exp || !ctrls->exposure->is_new) - return 0; - - exp = (u32)ctrls->exposure->val; - exp <<= 4; - - return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp); -} - -static int ov2680_exposure_get(struct ov2680_dev *sensor) -{ - int ret; - u32 exp; - - ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp); - if (ret) - return ret; - - return exp >> 4; + return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, + exp << 4); } static int ov2680_stream_enable(struct ov2680_dev *sensor) @@ -482,32 +422,16 @@ static int ov2680_stream_disable(struct ov2680_dev *sensor) static int ov2680_mode_set(struct ov2680_dev *sensor) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; int ret; - ret = ov2680_gain_set(sensor, false); - if (ret < 0) - return ret; - - ret = ov2680_exposure_set(sensor, false); - if (ret < 0) - return ret; - ret = ov2680_load_regs(sensor, sensor->current_mode); if (ret < 0) return ret; - if (ctrls->auto_gain->val) { - ret = ov2680_gain_set(sensor, true); - if (ret < 0) - return ret; - } - - if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) { - ret = ov2680_exposure_set(sensor, true); - if (ret < 0) - return ret; - } + /* Restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); + if (ret < 0) + return ret; sensor->mode_pending_changes = false; @@ -590,15 +514,10 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on) else ret = ov2680_power_off(sensor); - mutex_unlock(&sensor->lock); - - if (on && ret == 0) { - ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret < 0) - return ret; - + if (on && ret == 0) ret = ov2680_mode_restore(sensor); - } + + mutex_unlock(&sensor->lock); return ret; } @@ -794,52 +713,19 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, return 0; } -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); - struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; - int val; - - if (!sensor->is_enabled) - return 0; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - val = ov2680_gain_get(sensor); - if (val < 0) - return val; - ctrls->gain->val = val; - break; - case V4L2_CID_EXPOSURE: - val = ov2680_exposure_get(sensor); - if (val < 0) - return val; - ctrls->exposure->val = val; - break; - } - - return 0; -} - static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; if (!sensor->is_enabled) return 0; switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - return ov2680_gain_set(sensor, !!ctrl->val); case V4L2_CID_GAIN: - return ov2680_gain_set(sensor, !!ctrls->auto_gain->val); - case V4L2_CID_EXPOSURE_AUTO: - return ov2680_exposure_set(sensor, !!ctrl->val); + return ov2680_gain_set(sensor, ctrl->val); case V4L2_CID_EXPOSURE: - return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val); + return ov2680_exposure_set(sensor, ctrl->val); case V4L2_CID_VFLIP: if (sensor->is_streaming) return -EBUSY; @@ -864,7 +750,6 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) } static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { - .g_volatile_ctrl = ov2680_g_volatile_ctrl, .s_ctrl = ov2680_s_ctrl, }; @@ -936,7 +821,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) if (ret < 0) return ret; - v4l2_ctrl_handler_init(hdl, 7); + v4l2_ctrl_handler_init(hdl, 5); hdl->lock = &sensor->lock; @@ -948,16 +833,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, test_pattern_menu); - ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, - V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, - V4L2_EXPOSURE_AUTO); - ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, 32767, 1, 0); - ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, - 0, 1, 1, 1); ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); if (hdl->error) { @@ -965,14 +843,9 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) goto cleanup_entity; } - ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; - ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); - v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); - sensor->sd.ctrl_handler = hdl; ret = v4l2_async_register_subdev(&sensor->sd); From patchwork Thu Aug 3 09:33:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339584 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 5BD60C0015E for ; Thu, 3 Aug 2023 09:34:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235050AbjHCJeu (ORCPT ); Thu, 3 Aug 2023 05:34:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232097AbjHCJes (ORCPT ); Thu, 3 Aug 2023 05:34:48 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FE6630FD for ; Thu, 3 Aug 2023 02:33:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055238; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2L/idJTpHLCVGtZVMaKKXKlUK7PVEo6tb4VT8pB88HQ=; b=Z6CfGzzbgNU/wPJ90W38AL4a5+N268xhFjiAePVF+GVi7BSPYrixt/qY7oF8wB8hosXgWc fvFeP/9jzG0aHnONCnW3VhWuNiZTs4zKAgtgCrId7NnKAB3/a0kttvsABP6FCpvBi/GYef bif2lQVUKqxDyy1TT4V4Y1OfIfdfwSE= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-548-9rknVQ3WPHe3OlLqCQWVhg-1; Thu, 03 Aug 2023 05:33:54 -0400 X-MC-Unique: 9rknVQ3WPHe3OlLqCQWVhg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A8F183803508; Thu, 3 Aug 2023 09:33:53 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 42E0F2166B25; Thu, 3 Aug 2023 09:33:52 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 02/32] media: ov2680: Fix ov2680_bayer_order() Date: Thu, 3 Aug 2023 11:33:17 +0200 Message-ID: <20230803093348.15679-3-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The index into ov2680_hv_flip_bayer_order[] should be 0-3, but ov2680_bayer_order() was using 0 + BIT(2) + (BIT(2) << 1) as max index, while the intention was to use: 0 + 1 + 2 as max index. Fix the index calculation in ov2680_bayer_order(), while at it also just use the ctrl values rather then reading them back using a slow i2c-read transaction. This also allows making the function void, since there now are no more i2c-reads to error check. Note the check for the ctrls being NULL is there to allow adding an ov2680_fill_format() helper later, which will call ov2680_set_bayer_order() during probe() before the ctrls are created. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Reviewed-by: Daniel Scally Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 3a737a1607a4..621144f16fdc 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -315,26 +315,17 @@ static void ov2680_power_down(struct ov2680_dev *sensor) usleep_range(5000, 10000); } -static int ov2680_bayer_order(struct ov2680_dev *sensor) +static void ov2680_set_bayer_order(struct ov2680_dev *sensor) { - u32 format1; - u32 format2; - u32 hv_flip; - int ret; + int hv_flip = 0; - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1); - if (ret < 0) - return ret; + if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) + hv_flip += 1; - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2); - if (ret < 0) - return ret; - - hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2)); + if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) + hv_flip += 2; sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; - - return 0; } static int ov2680_vflip_enable(struct ov2680_dev *sensor) @@ -345,7 +336,8 @@ static int ov2680_vflip_enable(struct ov2680_dev *sensor) if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor); + return 0; } static int ov2680_vflip_disable(struct ov2680_dev *sensor) @@ -378,7 +370,8 @@ static int ov2680_hflip_disable(struct ov2680_dev *sensor) if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor); + return 0; } static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) From patchwork Thu Aug 3 09:33:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339586 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 7F330C04A6A for ; Thu, 3 Aug 2023 09:34:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235059AbjHCJex (ORCPT ); Thu, 3 Aug 2023 05:34:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235018AbjHCJes (ORCPT ); Thu, 3 Aug 2023 05:34:48 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1376F3582 for ; Thu, 3 Aug 2023 02:34:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055241; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7j4UG2P6TifUH18dZOHk5aY8Yhue/DQR2pIcbHH+qDU=; b=ghEjTmkZ2o+OY91OzSMuYf3H59kwgkk+l8hTkE9TRoH8o08iGkrwbXXusxuZcmTbKiewpq lwVZ4nAJLZwR/494O2pjISf8JjgZtN8Aj9ap86v+2UJb00cBBu2dN0WSnGc2CXyTfPZbCv JegxOaBLDskStfq1AbxioWtd6l72A6s= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-694-hTy97dESNjW0lG4s3D0pBg-1; Thu, 03 Aug 2023 05:33:55 -0400 X-MC-Unique: hTy97dESNjW0lG4s3D0pBg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4DDD480006E; Thu, 3 Aug 2023 09:33:55 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB5E92166B25; Thu, 3 Aug 2023 09:33:53 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 03/32] media: ov2680: Fix vflip / hflip set functions Date: Thu, 3 Aug 2023 11:33:18 +0200 Message-ID: <20230803093348.15679-4-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org ov2680_vflip_disable() / ov2680_hflip_disable() pass BIT(0) instead of 0 as value to ov2680_mod_reg(). While fixing this also: 1. Stop having separate enable/disable functions for hflip / vflip 2. Move the is_streaming check, which is unique to hflip / vflip into the ov2680_set_?flip() functions. for a nice code cleanup. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Reviewed-by: Daniel Scally Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 50 ++++++++++---------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 621144f16fdc..74024ba968b4 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -328,11 +328,15 @@ static void ov2680_set_bayer_order(struct ov2680_dev *sensor) sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; } -static int ov2680_vflip_enable(struct ov2680_dev *sensor) +static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2)); + if (sensor->is_streaming) + return -EBUSY; + + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; @@ -340,33 +344,15 @@ static int ov2680_vflip_enable(struct ov2680_dev *sensor) return 0; } -static int ov2680_vflip_disable(struct ov2680_dev *sensor) +static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0)); - if (ret < 0) - return ret; + if (sensor->is_streaming) + return -EBUSY; - return ov2680_bayer_order(sensor); -} - -static int ov2680_hflip_enable(struct ov2680_dev *sensor) -{ - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2)); - if (ret < 0) - return ret; - - return ov2680_bayer_order(sensor); -} - -static int ov2680_hflip_disable(struct ov2680_dev *sensor) -{ - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0)); + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; @@ -720,19 +706,9 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_EXPOSURE: return ov2680_exposure_set(sensor, ctrl->val); case V4L2_CID_VFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_vflip_enable(sensor); - else - return ov2680_vflip_disable(sensor); + return ov2680_set_vflip(sensor, ctrl->val); case V4L2_CID_HFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_hflip_enable(sensor); - else - return ov2680_hflip_disable(sensor); + return ov2680_set_hflip(sensor, ctrl->val); case V4L2_CID_TEST_PATTERN: return ov2680_test_pattern_set(sensor, ctrl->val); default: From patchwork Thu Aug 3 09:33:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339582 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 E8C64C0015E for ; Thu, 3 Aug 2023 09:34:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233295AbjHCJel (ORCPT ); Thu, 3 Aug 2023 05:34:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232097AbjHCJej (ORCPT ); Thu, 3 Aug 2023 05:34:39 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8176330FF for ; Thu, 3 Aug 2023 02:34:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=E3Kn4TsWrDw+ZJ+Mh6vLUTPtTgKM0u0Q2gCUlSm1+ik=; b=NyerCBRZLGXlzyQ04jGVLNYyzo7aJmwdxL5hIzibHWwnzrDc/GsOVVdHYIBvdinLL6PNAi lGXNu4MQBcKZz/xd1G51O4iBv74zu09pYapJ/DEis7CeUWl+PoL9S2IIGUm0Ga8KoJ2Qlc RZIwTKjRHMyXWAc5Fw6fSfW12dHugJY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-487-_rC2PgcxNDauW7nXRoPDAA-1; Thu, 03 Aug 2023 05:33:57 -0400 X-MC-Unique: _rC2PgcxNDauW7nXRoPDAA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 09C5C835154; Thu, 3 Aug 2023 09:33:57 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8219E2166B25; Thu, 3 Aug 2023 09:33:55 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 04/32] media: ov2680: Remove VIDEO_V4L2_SUBDEV_API ifdef-s Date: Thu, 3 Aug 2023 11:33:19 +0200 Message-ID: <20230803093348.15679-5-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org VIDEO_V4L2_SUBDEV_API is now automatically selected in Kconfig for all sensor drivers. Remove the ifdef CONFIG_VIDEO_V4L2_SUBDEV_API checks. This is a preparation patch for fixing ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY calls not properly filling in the passed in v4l2_mbus_framefmt struct. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Reviewed-by: Daniel Scally Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 74024ba968b4..5c1f5dd4824a 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -562,7 +562,6 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, { struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *fmt = NULL; - int ret = 0; if (format->pad != 0) return -EINVAL; @@ -570,22 +569,17 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, mutex_lock(&sensor->lock); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, format->pad); -#else - ret = -EINVAL; -#endif } else { fmt = &sensor->fmt; } - if (fmt) - format->format = *fmt; + format->format = *fmt; mutex_unlock(&sensor->lock); - return ret; + return 0; } static int ov2680_set_fmt(struct v4l2_subdev *sd, @@ -594,9 +588,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, { struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *fmt = &format->format; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *try_fmt; -#endif const struct ov2680_mode_info *mode; int ret = 0; @@ -619,10 +611,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, } if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *try_fmt; -#endif goto unlock; } @@ -780,9 +770,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) v4l2_i2c_subdev_init(&sensor->sd, sensor->i2c_client, &ov2680_subdev_ops); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; -#endif sensor->pad.flags = MEDIA_PAD_FL_SOURCE; sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; From patchwork Thu Aug 3 09:33:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339588 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 89F6FC41513 for ; Thu, 3 Aug 2023 09:35:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234678AbjHCJfS (ORCPT ); Thu, 3 Aug 2023 05:35:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234105AbjHCJfR (ORCPT ); Thu, 3 Aug 2023 05:35:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23C343581 for ; Thu, 3 Aug 2023 02:34:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055244; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SD/Q4kOCuAIFKVvnbpSujvy87YpdoGcbAqhupxdT/Y8=; b=A0bO4C6crkMbVDUlZggGR30OysypPRIj/Rm1orcYYjtBmzwd9FwnrK0O94NUwhI3IMCMtw fQB/rzsc52klkfvPjrjB1ENVhD5gzD2URJcluIjEGj44fDJYCMyRnwaYgceLb3CmTjlOTJ EdcvCMNj/YmtHYZ4Nhs/2EFUwLWibbU= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-541-Acz05F_6P6Svojj7-F8f3A-1; Thu, 03 Aug 2023 05:33:59 -0400 X-MC-Unique: Acz05F_6P6Svojj7-F8f3A-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A1767805AF7; Thu, 3 Aug 2023 09:33:58 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3C3842166B25; Thu, 3 Aug 2023 09:33:57 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 05/32] media: ov2680: Don't take the lock for try_fmt calls Date: Thu, 3 Aug 2023 11:33:20 +0200 Message-ID: <20230803093348.15679-6-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On ov2680_set_fmt() calls with format->which == V4L2_SUBDEV_FORMAT_TRY, ov2680_set_fmt() does not talk to the sensor. So in this case there is no need to lock the sensor->lock mutex or to check that the sensor is streaming. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 5c1f5dd4824a..e6e14743ba1e 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -595,24 +595,22 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, if (format->pad != 0) return -EINVAL; - mutex_lock(&sensor->lock); - - if (sensor->is_streaming) { - ret = -EBUSY; - goto unlock; - } - mode = v4l2_find_nearest_size(ov2680_mode_data, ARRAY_SIZE(ov2680_mode_data), width, height, fmt->width, fmt->height); - if (!mode) { - ret = -EINVAL; - goto unlock; - } + if (!mode) + return -EINVAL; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *try_fmt; + return 0; + } + + mutex_lock(&sensor->lock); + + if (sensor->is_streaming) { + ret = -EBUSY; goto unlock; } From patchwork Thu Aug 3 09:33:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339587 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 EC424C00528 for ; Thu, 3 Aug 2023 09:35:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234508AbjHCJfS (ORCPT ); Thu, 3 Aug 2023 05:35:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234028AbjHCJfQ (ORCPT ); Thu, 3 Aug 2023 05:35:16 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 598A93583 for ; Thu, 3 Aug 2023 02:34:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055245; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ApOx9JYyYB42Wtd+wLJUGbXCtlI48Gdo4YHkbgnoBTw=; b=ctkHOjgxxhkIaQ7XBFa7j3JFIcwVN5TFL8L0mZ6EFwzeWyPgdwIEj/acqYo5Jdtx6vyqlh Ndabnw03qePsiO2NrkfYMJPukp9Xf6Wq/svKvuslcGdMMIm0iGcRedFNhWS+IPyHdl8ra9 LkCj9gKlnqbUxc9lDmul/4Qkt74wwnI= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-505-jRJsrN6tO2Ge7lTqWyPfDA-1; Thu, 03 Aug 2023 05:34:02 -0400 X-MC-Unique: jRJsrN6tO2Ge7lTqWyPfDA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 49956104458E; Thu, 3 Aug 2023 09:34:01 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id D412C2166B25; Thu, 3 Aug 2023 09:33:58 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 06/32] media: ov2680: Add ov2680_fill_format() helper function Date: Thu, 3 Aug 2023 11:33:21 +0200 Message-ID: <20230803093348.15679-7-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add a ov2680_fill_format() helper function and use this everywhere were a v4l2_mbus_framefmt struct needs to be filled in so that the driver always fills it consistently. This is a preparation patch for fixing ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY calls not properly filling in the passed in v4l2_mbus_framefmt struct. Note that for ov2680_init_cfg() this now simply always fills the try_fmt struct of the passed in sd_state. This is correct because ov2680_init_cfg() is never called with a NULL sd_state so the old sd_state check is not necessary. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 49 +++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index e6e14743ba1e..f2eb8d85a7e4 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -54,6 +54,9 @@ #define OV2680_WIDTH_MAX 1600 #define OV2680_HEIGHT_MAX 1200 +#define OV2680_DEFAULT_WIDTH 800 +#define OV2680_DEFAULT_HEIGHT 600 + enum ov2680_mode_id { OV2680_MODE_QUXGA_800_600, OV2680_MODE_720P_1280_720, @@ -315,7 +318,8 @@ static void ov2680_power_down(struct ov2680_dev *sensor) usleep_range(5000, 10000); } -static void ov2680_set_bayer_order(struct ov2680_dev *sensor) +static void ov2680_set_bayer_order(struct ov2680_dev *sensor, + struct v4l2_mbus_framefmt *fmt) { int hv_flip = 0; @@ -325,7 +329,19 @@ static void ov2680_set_bayer_order(struct ov2680_dev *sensor) if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) hv_flip += 2; - sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; + fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; +} + +static void ov2680_fill_format(struct ov2680_dev *sensor, + struct v4l2_mbus_framefmt *fmt, + unsigned int width, unsigned int height) +{ + memset(fmt, 0, sizeof(*fmt)); + fmt->width = width; + fmt->height = height; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + ov2680_set_bayer_order(sensor, fmt); } static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) @@ -340,7 +356,7 @@ static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) if (ret < 0) return ret; - ov2680_set_bayer_order(sensor); + ov2680_set_bayer_order(sensor, &sensor->fmt); return 0; } @@ -356,7 +372,7 @@ static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) if (ret < 0) return ret; - ov2680_set_bayer_order(sensor); + ov2680_set_bayer_order(sensor, &sensor->fmt); return 0; } @@ -614,10 +630,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, goto unlock; } - fmt->width = mode->width; - fmt->height = mode->height; - fmt->code = sensor->fmt.code; - fmt->colorspace = sensor->fmt.colorspace; + ov2680_fill_format(sensor, fmt, mode->width, mode->height); sensor->current_mode = mode; sensor->fmt = format->format; @@ -632,16 +645,11 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, static int ov2680_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { - struct v4l2_subdev_format fmt = { - .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, - .format = { - .width = 800, - .height = 600, - } - }; + struct ov2680_dev *sensor = to_ov2680_dev(sd); - return ov2680_set_fmt(sd, sd_state, &fmt); + ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt, + OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); + return 0; } static int ov2680_enum_frame_size(struct v4l2_subdev *sd, @@ -740,11 +748,8 @@ static int ov2680_mode_init(struct ov2680_dev *sensor) const struct ov2680_mode_info *init_mode; /* set initial mode */ - sensor->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10; - sensor->fmt.width = 800; - sensor->fmt.height = 600; - sensor->fmt.field = V4L2_FIELD_NONE; - sensor->fmt.colorspace = V4L2_COLORSPACE_SRGB; + ov2680_fill_format(sensor, &sensor->fmt, + OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); sensor->frame_interval.denominator = OV2680_FRAME_RATE; sensor->frame_interval.numerator = 1; From patchwork Thu Aug 3 09:33:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339589 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 69D3CC0015E for ; Thu, 3 Aug 2023 09:35:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234920AbjHCJf1 (ORCPT ); Thu, 3 Aug 2023 05:35:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234030AbjHCJf0 (ORCPT ); Thu, 3 Aug 2023 05:35:26 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C3B43586 for ; Thu, 3 Aug 2023 02:34:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055248; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O9w4uNOwbqzVoyjEtyPAFZuh3Lv5724m4ELXWMJyChI=; b=RYhm8Sf3KF0Xe3MF5/gaj6lA60xHpo6uTA6XxQH0alDDv+ICZWpzbHmHYh/Katd5xvNjiQ 1EqF/M88HqplBnO93EEbDWI563I1FyPnZRtlhj40CyrY8mFgNfLrMXNDiB5zKW5hXM09nm tqnW7zPZfvRTuUSz9koUyenYbOdeBpA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-673-Kipky0HrMAyNxDnfgWBZsg-1; Thu, 03 Aug 2023 05:34:03 -0400 X-MC-Unique: Kipky0HrMAyNxDnfgWBZsg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E090F104458A; Thu, 3 Aug 2023 09:34:02 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7BEC62166B25; Thu, 3 Aug 2023 09:34:01 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 07/32] media: ov2680: Fix ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY not working Date: Thu, 3 Aug 2023 11:33:22 +0200 Message-ID: <20230803093348.15679-8-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY was getting the try_fmt v4l2_mbus_framefmt struct from the passed in sd_state and then storing the contents of that into the return by reference format->format struct. While the right thing to do would be filling format->format based on the just looked up mode and then store the results of that in sd_state->pads[0].try_fmt . Before the previous change introducing ov2680_fill_format() this resulted in ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY always returning the zero-ed out sd_state->pads[0].try_fmt in format->format breaking callers using this. After the introduction of ov2680_fill_format() which at least initializes sd_state->pads[0].try_fmt properly, format->format is now always being filled with the default 800x600 mode set by ov2680_init_cfg() independent of the actual requested mode. Move the filling of format->format with ov2680_fill_format() to before the if (which == V4L2_SUBDEV_FORMAT_TRY) and then store the filled in format->format in sd_state->pads[0].try_fmt to fix this. Note this removes the fmt local variable because IMHO having a local variable which points to a sub-struct of one of the function arguments just leads to confusion when reading the code. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index f2eb8d85a7e4..e3652b5394c4 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -603,7 +603,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct v4l2_mbus_framefmt *fmt = &format->format; struct v4l2_mbus_framefmt *try_fmt; const struct ov2680_mode_info *mode; int ret = 0; @@ -612,14 +611,18 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, return -EINVAL; mode = v4l2_find_nearest_size(ov2680_mode_data, - ARRAY_SIZE(ov2680_mode_data), width, - height, fmt->width, fmt->height); + ARRAY_SIZE(ov2680_mode_data), + width, height, + format->format.width, + format->format.height); if (!mode) return -EINVAL; + ov2680_fill_format(sensor, &format->format, mode->width, mode->height); + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); - format->format = *try_fmt; + *try_fmt = format->format; return 0; } @@ -630,8 +633,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, goto unlock; } - ov2680_fill_format(sensor, fmt, mode->width, mode->height); - sensor->current_mode = mode; sensor->fmt = format->format; sensor->mode_pending_changes = true; From patchwork Thu Aug 3 09:33:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339590 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 B0C24C04A6A for ; Thu, 3 Aug 2023 09:35:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235061AbjHCJf3 (ORCPT ); Thu, 3 Aug 2023 05:35:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33324 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234030AbjHCJf2 (ORCPT ); Thu, 3 Aug 2023 05:35:28 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2593358B for ; Thu, 3 Aug 2023 02:34:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055250; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kemH3TIGjsRjAmEGqlg6Np7m9pndL4C5+2GpW0YrgzE=; b=UptuEEGlrB/RDnTecuPjce9IX/wlc18MOvhNhcysX0rz1EmgPdjiIPbmfkWd8BxNC4dStz G/J9kbmULL84v3CL3ehBl6dPnT8jpxJRUEqv17zkUj7babCZUc0TS5Q7bKh9iuL2sAIrMw AaCLqF8eqBAnetZf3qYSFUwn5/YCL2E= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-689-vSivb_6vPlaBg7kQKBmLvQ-1; Thu, 03 Aug 2023 05:34:05 -0400 X-MC-Unique: vSivb_6vPlaBg7kQKBmLvQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 84EF21C0754F; Thu, 3 Aug 2023 09:34:04 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1EA022166B25; Thu, 3 Aug 2023 09:34:03 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 08/32] media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors Date: Thu, 3 Aug 2023 11:33:23 +0200 Message-ID: <20230803093348.15679-9-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org When the ov2680_power_on() "sensor soft reset failed" path is hit during probe() the WARN() about putting an enabled regulator at drivers/regulator/core.c:2398 triggers 3 times (once for each regulator), filling dmesg with backtraces. Fix this by properly disabling the regulators on ov2680_power_on() errors. Fixes: 3ee47cad3e69 ("media: ov2680: Add Omnivision OV2680 sensor driver") Reviewed-by: Daniel Scally Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index e3652b5394c4..1f923acbbc07 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -475,7 +475,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); if (ret != 0) { dev_err(dev, "sensor soft reset failed\n"); - return ret; + goto err_disable_regulators; } usleep_range(1000, 2000); } else { @@ -485,7 +485,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) ret = clk_prepare_enable(sensor->xvclk); if (ret < 0) - return ret; + goto err_disable_regulators; sensor->is_enabled = true; @@ -495,6 +495,10 @@ static int ov2680_power_on(struct ov2680_dev *sensor) ov2680_stream_disable(sensor); return 0; + +err_disable_regulators: + regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); + return ret; } static int ov2680_s_power(struct v4l2_subdev *sd, int on) From patchwork Thu Aug 3 09:33:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339591 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 BE9E6C0015E for ; Thu, 3 Aug 2023 09:35:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235062AbjHCJfa (ORCPT ); Thu, 3 Aug 2023 05:35:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235018AbjHCJf2 (ORCPT ); Thu, 3 Aug 2023 05:35:28 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8A6C4358D for ; Thu, 3 Aug 2023 02:34:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055250; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=q3MA44Ema+uNPDJkgWrO8iTRnhCzEMkhsNWD8j7RjXk=; b=Fm0NFADTPL/j0d4107uD9Zp4Da4qNLHZ+rQzK6kHDP67O2Fz/w0c+c/TRCsibTdXY/5U6g 08PhDAQVN3JHuQVbPVeYiLzFETqBrBb6uNB3U7gXGWgNwdB1mFbqo1TPZHc2Z0WlEB+Bj2 EOOLgog9ohD1jrpubq0UEcOuo8rk53U= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-610-u1onL2SMMdmTaOo0I8m3mQ-1; Thu, 03 Aug 2023 05:34:06 -0400 X-MC-Unique: u1onL2SMMdmTaOo0I8m3mQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2E19F3C0CEE2; Thu, 3 Aug 2023 09:34:06 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id B84A02166B25; Thu, 3 Aug 2023 09:34:04 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 09/32] media: ov2680: Convert to new CCI register access helpers Date: Thu, 3 Aug 2023 11:33:24 +0200 Message-ID: <20230803093348.15679-10-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Use the new comon CCI register access helpers to replace the private register access helpers in the ov2680 driver. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/ov2680.c | 224 ++++++++++--------------------------- 2 files changed, 58 insertions(+), 167 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index aa55582a2cd0..74ff833ff48c 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -332,6 +332,7 @@ config VIDEO_OV2659 config VIDEO_OV2680 tristate "OmniVision OV2680 sensor support" + select V4L2_CCI_I2C help This is a Video4Linux2 sensor driver for the OmniVision OV2680 camera. diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 1f923acbbc07..02ac5b5e6583 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -10,49 +10,45 @@ * */ -#include #include #include #include +#include #include #include #include #include -#include +#include #include +#include #include #include #include -#define OV2680_XVCLK_VALUE 24000000 +#define OV2680_XVCLK_VALUE 24000000 -#define OV2680_CHIP_ID 0x2680 +#define OV2680_CHIP_ID 0x2680 -#define OV2680_REG_STREAM_CTRL 0x0100 -#define OV2680_REG_SOFT_RESET 0x0103 +#define OV2680_REG_STREAM_CTRL CCI_REG8(0x0100) +#define OV2680_REG_SOFT_RESET CCI_REG8(0x0103) -#define OV2680_REG_CHIP_ID_HIGH 0x300a -#define OV2680_REG_CHIP_ID_LOW 0x300b +#define OV2680_REG_CHIP_ID CCI_REG16(0x300a) -#define OV2680_REG_R_MANUAL 0x3503 -#define OV2680_REG_GAIN_PK 0x350a -#define OV2680_REG_EXPOSURE_PK_HIGH 0x3500 -#define OV2680_REG_TIMING_HTS 0x380c -#define OV2680_REG_TIMING_VTS 0x380e -#define OV2680_REG_FORMAT1 0x3820 -#define OV2680_REG_FORMAT2 0x3821 +#define OV2680_REG_EXPOSURE_PK CCI_REG24(0x3500) +#define OV2680_REG_R_MANUAL CCI_REG8(0x3503) +#define OV2680_REG_GAIN_PK CCI_REG16(0x350a) +#define OV2680_REG_TIMING_HTS CCI_REG16(0x380c) +#define OV2680_REG_TIMING_VTS CCI_REG16(0x380e) +#define OV2680_REG_FORMAT1 CCI_REG8(0x3820) +#define OV2680_REG_FORMAT2 CCI_REG8(0x3821) -#define OV2680_REG_ISP_CTRL00 0x5080 +#define OV2680_REG_ISP_CTRL00 CCI_REG8(0x5080) -#define OV2680_FRAME_RATE 30 +#define OV2680_FRAME_RATE 30 -#define OV2680_REG_VALUE_8BIT 1 -#define OV2680_REG_VALUE_16BIT 2 -#define OV2680_REG_VALUE_24BIT 3 - -#define OV2680_WIDTH_MAX 1600 -#define OV2680_HEIGHT_MAX 1200 +#define OV2680_WIDTH_MAX 1600 +#define OV2680_HEIGHT_MAX 1200 #define OV2680_DEFAULT_WIDTH 800 #define OV2680_DEFAULT_HEIGHT 600 @@ -64,11 +60,6 @@ enum ov2680_mode_id { OV2680_MODE_MAX, }; -struct reg_value { - u16 reg_addr; - u8 val; -}; - static const char * const ov2680_supply_name[] = { "DOVDD", "DVDD", @@ -82,7 +73,7 @@ struct ov2680_mode_info { enum ov2680_mode_id id; u32 width; u32 height; - const struct reg_value *reg_data; + const struct reg_sequence *reg_data; u32 reg_data_size; }; @@ -97,6 +88,7 @@ struct ov2680_ctrls { struct ov2680_dev { struct i2c_client *i2c_client; + struct regmap *regmap; struct v4l2_subdev sd; struct media_pad pad; @@ -133,7 +125,7 @@ static const int ov2680_hv_flip_bayer_order[] = { MEDIA_BUS_FMT_SRGGB10_1X10, }; -static const struct reg_value ov2680_setting_30fps_QUXGA_800_600[] = { +static const struct reg_sequence ov2680_setting_30fps_QUXGA_800_600[] = { {0x3086, 0x01}, {0x370a, 0x23}, {0x3808, 0x03}, {0x3809, 0x20}, {0x380a, 0x02}, {0x380b, 0x58}, {0x380c, 0x06}, {0x380d, 0xac}, {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, @@ -142,14 +134,14 @@ static const struct reg_value ov2680_setting_30fps_QUXGA_800_600[] = { {0x3503, 0x03}, }; -static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { +static const struct reg_sequence ov2680_setting_30fps_720P_1280_720[] = { {0x3086, 0x00}, {0x3808, 0x05}, {0x3809, 0x00}, {0x380a, 0x02}, {0x380b, 0xd0}, {0x380c, 0x06}, {0x380d, 0xa8}, {0x380e, 0x05}, {0x380f, 0x0e}, {0x3811, 0x08}, {0x3813, 0x06}, {0x3814, 0x11}, {0x3815, 0x11}, {0x3820, 0xc0}, {0x4008, 0x00}, }; -static const struct reg_value ov2680_setting_30fps_UXGA_1600_1200[] = { +static const struct reg_sequence ov2680_setting_30fps_UXGA_1600_1200[] = { {0x3086, 0x00}, {0x3501, 0x4e}, {0x3502, 0xe0}, {0x3808, 0x06}, {0x3809, 0x40}, {0x380a, 0x04}, {0x380b, 0xb0}, {0x380c, 0x06}, {0x380d, 0xa8}, {0x380e, 0x05}, {0x380f, 0x0e}, {0x3811, 0x00}, @@ -191,115 +183,6 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) ctrls.handler)->sd; } -static int __ov2680_write_reg(struct ov2680_dev *sensor, u16 reg, - unsigned int len, u32 val) -{ - struct i2c_client *client = sensor->i2c_client; - u8 buf[6]; - int ret; - - if (len > 4) - return -EINVAL; - - put_unaligned_be16(reg, buf); - put_unaligned_be32(val << (8 * (4 - len)), buf + 2); - ret = i2c_master_send(client, buf, len + 2); - if (ret != len + 2) { - dev_err(&client->dev, "write error: reg=0x%4x: %d\n", reg, ret); - return -EIO; - } - - return 0; -} - -#define ov2680_write_reg(s, r, v) \ - __ov2680_write_reg(s, r, OV2680_REG_VALUE_8BIT, v) - -#define ov2680_write_reg16(s, r, v) \ - __ov2680_write_reg(s, r, OV2680_REG_VALUE_16BIT, v) - -#define ov2680_write_reg24(s, r, v) \ - __ov2680_write_reg(s, r, OV2680_REG_VALUE_24BIT, v) - -static int __ov2680_read_reg(struct ov2680_dev *sensor, u16 reg, - unsigned int len, u32 *val) -{ - struct i2c_client *client = sensor->i2c_client; - struct i2c_msg msgs[2]; - u8 addr_buf[2] = { reg >> 8, reg & 0xff }; - u8 data_buf[4] = { 0, }; - int ret; - - if (len > 4) - return -EINVAL; - - msgs[0].addr = client->addr; - msgs[0].flags = 0; - msgs[0].len = ARRAY_SIZE(addr_buf); - msgs[0].buf = addr_buf; - - msgs[1].addr = client->addr; - msgs[1].flags = I2C_M_RD; - msgs[1].len = len; - msgs[1].buf = &data_buf[4 - len]; - - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (ret != ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "read error: reg=0x%4x: %d\n", reg, ret); - return -EIO; - } - - *val = get_unaligned_be32(data_buf); - - return 0; -} - -#define ov2680_read_reg(s, r, v) \ - __ov2680_read_reg(s, r, OV2680_REG_VALUE_8BIT, v) - -#define ov2680_read_reg16(s, r, v) \ - __ov2680_read_reg(s, r, OV2680_REG_VALUE_16BIT, v) - -#define ov2680_read_reg24(s, r, v) \ - __ov2680_read_reg(s, r, OV2680_REG_VALUE_24BIT, v) - -static int ov2680_mod_reg(struct ov2680_dev *sensor, u16 reg, u8 mask, u8 val) -{ - u32 readval; - int ret; - - ret = ov2680_read_reg(sensor, reg, &readval); - if (ret < 0) - return ret; - - readval &= ~mask; - val &= mask; - val |= readval; - - return ov2680_write_reg(sensor, reg, val); -} - -static int ov2680_load_regs(struct ov2680_dev *sensor, - const struct ov2680_mode_info *mode) -{ - const struct reg_value *regs = mode->reg_data; - unsigned int i; - int ret = 0; - u16 reg_addr; - u8 val; - - for (i = 0; i < mode->reg_data_size; ++i, ++regs) { - reg_addr = regs->reg_addr; - val = regs->val; - - ret = ov2680_write_reg(sensor, reg_addr, val); - if (ret) - break; - } - - return ret; -} - static void ov2680_power_up(struct ov2680_dev *sensor) { if (!sensor->reset_gpio) @@ -351,8 +234,8 @@ static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) if (sensor->is_streaming) return -EBUSY; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, - BIT(2), val ? BIT(2) : 0); + ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT1, + BIT(2), val ? BIT(2) : 0, NULL); if (ret < 0) return ret; @@ -367,8 +250,8 @@ static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) if (sensor->is_streaming) return -EBUSY; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, - BIT(2), val ? BIT(2) : 0); + ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT2, + BIT(2), val ? BIT(2) : 0, NULL); if (ret < 0) return ret; @@ -378,48 +261,48 @@ static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) { - int ret; + int ret = 0; if (!value) - return ov2680_mod_reg(sensor, OV2680_REG_ISP_CTRL00, BIT(7), 0); + return cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, + BIT(7), 0, NULL); - ret = ov2680_mod_reg(sensor, OV2680_REG_ISP_CTRL00, 0x03, value - 1); - if (ret < 0) - return ret; + cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, + 0x03, value - 1, &ret); + cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, + BIT(7), BIT(7), &ret); - ret = ov2680_mod_reg(sensor, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7)); - if (ret < 0) - return ret; - - return 0; + return ret; } static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) { - return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); + return cci_write(sensor->regmap, OV2680_REG_GAIN_PK, gain, NULL); } static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) { - return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, - exp << 4); + return cci_write(sensor->regmap, OV2680_REG_EXPOSURE_PK, exp << 4, + NULL); } static int ov2680_stream_enable(struct ov2680_dev *sensor) { - return ov2680_write_reg(sensor, OV2680_REG_STREAM_CTRL, 1); + return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 1, NULL); } static int ov2680_stream_disable(struct ov2680_dev *sensor) { - return ov2680_write_reg(sensor, OV2680_REG_STREAM_CTRL, 0); + return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 0, NULL); } static int ov2680_mode_set(struct ov2680_dev *sensor) { int ret; - ret = ov2680_load_regs(sensor, sensor->current_mode); + ret = regmap_multi_reg_write(sensor->regmap, + sensor->current_mode->reg_data, + sensor->current_mode->reg_data_size); if (ret < 0) return ret; @@ -437,7 +320,9 @@ static int ov2680_mode_restore(struct ov2680_dev *sensor) { int ret; - ret = ov2680_load_regs(sensor, &ov2680_mode_init_data); + ret = regmap_multi_reg_write(sensor->regmap, + ov2680_mode_init_data.reg_data, + ov2680_mode_init_data.reg_data_size); if (ret < 0) return ret; @@ -472,7 +357,8 @@ static int ov2680_power_on(struct ov2680_dev *sensor) } if (!sensor->reset_gpio) { - ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); + ret = cci_write(sensor->regmap, OV2680_REG_SOFT_RESET, 0x01, + NULL); if (ret != 0) { dev_err(dev, "sensor soft reset failed\n"); goto err_disable_regulators; @@ -841,19 +727,19 @@ static int ov2680_get_regulators(struct ov2680_dev *sensor) static int ov2680_check_id(struct ov2680_dev *sensor) { struct device *dev = ov2680_to_dev(sensor); - u32 chip_id; + u64 chip_id; int ret; ov2680_power_on(sensor); - ret = ov2680_read_reg16(sensor, OV2680_REG_CHIP_ID_HIGH, &chip_id); + ret = cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, NULL); if (ret < 0) { - dev_err(dev, "failed to read chip id high\n"); + dev_err(dev, "failed to read chip id\n"); return -ENODEV; } if (chip_id != OV2680_CHIP_ID) { - dev_err(dev, "chip id: 0x%04x does not match expected 0x%04x\n", + dev_err(dev, "chip id: 0x%04llx does not match expected 0x%04x\n", chip_id, OV2680_CHIP_ID); return -ENODEV; } @@ -902,6 +788,10 @@ static int ov2680_probe(struct i2c_client *client) sensor->i2c_client = client; + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(sensor->regmap)) + return PTR_ERR(sensor->regmap); + ret = ov2680_parse_dt(sensor); if (ret < 0) return -EINVAL; From patchwork Thu Aug 3 09:33:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339594 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 6BBD3C04A6A for ; Thu, 3 Aug 2023 09:35:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235096AbjHCJfi (ORCPT ); Thu, 3 Aug 2023 05:35:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33374 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234671AbjHCJff (ORCPT ); Thu, 3 Aug 2023 05:35:35 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 597173594 for ; Thu, 3 Aug 2023 02:34:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055251; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lFiJHISLDjnVcVI01/mMSh+3yKDmTzDpt++S64j0wzs=; b=SPBF06VgeWiHSgsDumWxElbD5vL625+fXAz2NxOT9vETClM3kFCtN0KHm66NqXvTPzXt0W MvNRYr2mDY/DtQZtbVfKy7wTYHm+VdMDCqSf8Nev9sSIg7sd6Ygq2Pagekq/MnJY7UO19y MIrFe4QuYnWTbiRglF3YZzuE1qnqGq0= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-155-8zDHflxQMrKnEOdSFKK8Tg-1; Thu, 03 Aug 2023 05:34:08 -0400 X-MC-Unique: 8zDHflxQMrKnEOdSFKK8Tg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C76173803508; Thu, 3 Aug 2023 09:34:07 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 60CDB2166B25; Thu, 3 Aug 2023 09:34:06 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 10/32] media: ov2680: Store dev instead of i2c_client in ov2680_dev Date: Thu, 3 Aug 2023 11:33:25 +0200 Message-ID: <20230803093348.15679-11-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Now that the cci_* register access helpers are used access to the i2c_client after probe() is no longer necessary. Directly store a struct device *dev pointing to &client->dev inside ov2680_dev to make the code simpler. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- Changes in v2: - Use to_i2c_client(sensor->dev) in ov2680_v4l2_register() --- drivers/media/i2c/ov2680.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 02ac5b5e6583..9c5f4ac592d8 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -87,7 +87,7 @@ struct ov2680_ctrls { }; struct ov2680_dev { - struct i2c_client *i2c_client; + struct device *dev; struct regmap *regmap; struct v4l2_subdev sd; @@ -172,11 +172,6 @@ static struct ov2680_dev *to_ov2680_dev(struct v4l2_subdev *sd) return container_of(sd, struct ov2680_dev, sd); } -static struct device *ov2680_to_dev(struct ov2680_dev *sensor) -{ - return &sensor->i2c_client->dev; -} - static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) { return &container_of(ctrl->handler, struct ov2680_dev, @@ -344,7 +339,6 @@ static int ov2680_power_off(struct ov2680_dev *sensor) static int ov2680_power_on(struct ov2680_dev *sensor) { - struct device *dev = ov2680_to_dev(sensor); int ret; if (sensor->is_enabled) @@ -352,7 +346,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) ret = regulator_bulk_enable(OV2680_NUM_SUPPLIES, sensor->supplies); if (ret < 0) { - dev_err(dev, "failed to enable regulators: %d\n", ret); + dev_err(sensor->dev, "failed to enable regulators: %d\n", ret); return ret; } @@ -360,7 +354,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) ret = cci_write(sensor->regmap, OV2680_REG_SOFT_RESET, 0x01, NULL); if (ret != 0) { - dev_err(dev, "sensor soft reset failed\n"); + dev_err(sensor->dev, "sensor soft reset failed\n"); goto err_disable_regulators; } usleep_range(1000, 2000); @@ -656,13 +650,13 @@ static int ov2680_mode_init(struct ov2680_dev *sensor) static int ov2680_v4l2_register(struct ov2680_dev *sensor) { + struct i2c_client *client = to_i2c_client(sensor->dev); const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops; struct ov2680_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; int ret = 0; - v4l2_i2c_subdev_init(&sensor->sd, sensor->i2c_client, - &ov2680_subdev_ops); + v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_subdev_ops); sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; @@ -719,14 +713,12 @@ static int ov2680_get_regulators(struct ov2680_dev *sensor) for (i = 0; i < OV2680_NUM_SUPPLIES; i++) sensor->supplies[i].supply = ov2680_supply_name[i]; - return devm_regulator_bulk_get(&sensor->i2c_client->dev, - OV2680_NUM_SUPPLIES, - sensor->supplies); + return devm_regulator_bulk_get(sensor->dev, + OV2680_NUM_SUPPLIES, sensor->supplies); } static int ov2680_check_id(struct ov2680_dev *sensor) { - struct device *dev = ov2680_to_dev(sensor); u64 chip_id; int ret; @@ -734,12 +726,12 @@ static int ov2680_check_id(struct ov2680_dev *sensor) ret = cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, NULL); if (ret < 0) { - dev_err(dev, "failed to read chip id\n"); + dev_err(sensor->dev, "failed to read chip id\n"); return -ENODEV; } if (chip_id != OV2680_CHIP_ID) { - dev_err(dev, "chip id: 0x%04llx does not match expected 0x%04x\n", + dev_err(sensor->dev, "chip id: 0x%04llx does not match expected 0x%04x\n", chip_id, OV2680_CHIP_ID); return -ENODEV; } @@ -749,7 +741,7 @@ static int ov2680_check_id(struct ov2680_dev *sensor) static int ov2680_parse_dt(struct ov2680_dev *sensor) { - struct device *dev = ov2680_to_dev(sensor); + struct device *dev = sensor->dev; int ret; sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", @@ -786,7 +778,7 @@ static int ov2680_probe(struct i2c_client *client) if (!sensor) return -ENOMEM; - sensor->i2c_client = client; + sensor->dev = &client->dev; sensor->regmap = devm_cci_regmap_init_i2c(client, 16); if (IS_ERR(sensor->regmap)) From patchwork Thu Aug 3 09:33:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339596 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 03CDCC04FE0 for ; Thu, 3 Aug 2023 09:35:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235092AbjHCJfk (ORCPT ); Thu, 3 Aug 2023 05:35:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235070AbjHCJfg (ORCPT ); Thu, 3 Aug 2023 05:35:36 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5D2DF3595 for ; Thu, 3 Aug 2023 02:34:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055252; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qH0OOmAsuNZcXhZjRcIrUeyNAMQW8M/TkknGnwMEuAU=; b=MI+RnadgSuJoaOeXyKzoO/pL21sebxHQPFTI6C3DMnqfuokOAOzgGKT8nesXx2SChbabGf RNne/SYWrSrpeE2FvzVr5BipEczvXMcCZhOUNo+ZZipkt2NydhweuSwCLAAuM4DpTHE73T Jmb/MwVPaaQxnks5O0RdeT4gVtP3xvY= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-34-DzWjU-FKNWOXWVrZutF3Vw-1; Thu, 03 Aug 2023 05:34:10 -0400 X-MC-Unique: DzWjU-FKNWOXWVrZutF3Vw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6F6FF2808B23; Thu, 3 Aug 2023 09:34:09 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 055DD2166B25; Thu, 3 Aug 2023 09:34:07 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 11/32] media: ov2680: Add runtime-pm support Date: Thu, 3 Aug 2023 11:33:26 +0200 Message-ID: <20230803093348.15679-12-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Remove the obsolete s_power() callback and instead use runtime-pm + autosuspend, powering-on the sensor on s_stream(1) and releasing the runtime-pm reference on s_stream(0). This also removes the need for ov2680_mode_restore() instead ov2680_stream_enable() now takes care of all sensor initalization after power-on. This is a preparation patch for adding ACPI support. Note this also removes putting the clock lane into LP-11 state from ov2680_power_on() since now streaming will start immediately after powering on the sensor there is no need to put the clock lane in a low power state. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 134 +++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 73 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 9c5f4ac592d8..bc0ca2927370 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -99,7 +100,6 @@ struct ov2680_dev { struct gpio_desc *reset_gpio; struct mutex lock; /* protect members */ - bool mode_pending_changes; bool is_enabled; bool is_streaming; @@ -282,19 +282,15 @@ static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) } static int ov2680_stream_enable(struct ov2680_dev *sensor) -{ - return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 1, NULL); -} - -static int ov2680_stream_disable(struct ov2680_dev *sensor) -{ - return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 0, NULL); -} - -static int ov2680_mode_set(struct ov2680_dev *sensor) { int ret; + ret = regmap_multi_reg_write(sensor->regmap, + ov2680_mode_init_data.reg_data, + ov2680_mode_init_data.reg_data_size); + if (ret < 0) + return ret; + ret = regmap_multi_reg_write(sensor->regmap, sensor->current_mode->reg_data, sensor->current_mode->reg_data_size); @@ -306,22 +302,12 @@ static int ov2680_mode_set(struct ov2680_dev *sensor) if (ret < 0) return ret; - sensor->mode_pending_changes = false; - - return 0; + return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 1, NULL); } -static int ov2680_mode_restore(struct ov2680_dev *sensor) +static int ov2680_stream_disable(struct ov2680_dev *sensor) { - int ret; - - ret = regmap_multi_reg_write(sensor->regmap, - ov2680_mode_init_data.reg_data, - ov2680_mode_init_data.reg_data_size); - if (ret < 0) - return ret; - - return ov2680_mode_set(sensor); + return cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 0, NULL); } static int ov2680_power_off(struct ov2680_dev *sensor) @@ -369,11 +355,6 @@ static int ov2680_power_on(struct ov2680_dev *sensor) sensor->is_enabled = true; - /* Set clock lane into LP-11 state */ - ov2680_stream_enable(sensor); - usleep_range(1000, 2000); - ov2680_stream_disable(sensor); - return 0; err_disable_regulators: @@ -381,26 +362,6 @@ static int ov2680_power_on(struct ov2680_dev *sensor) return ret; } -static int ov2680_s_power(struct v4l2_subdev *sd, int on) -{ - struct ov2680_dev *sensor = to_ov2680_dev(sd); - int ret = 0; - - mutex_lock(&sensor->lock); - - if (on) - ret = ov2680_power_on(sensor); - else - ret = ov2680_power_off(sensor); - - if (on && ret == 0) - ret = ov2680_mode_restore(sensor); - - mutex_unlock(&sensor->lock); - - return ret; -} - static int ov2680_s_g_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *fi) { @@ -423,16 +384,20 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable) if (sensor->is_streaming == !!enable) goto unlock; - if (enable && sensor->mode_pending_changes) { - ret = ov2680_mode_set(sensor); + if (enable) { + ret = pm_runtime_resume_and_get(sensor->sd.dev); if (ret < 0) goto unlock; - } - if (enable) ret = ov2680_stream_enable(sensor); - else + if (ret < 0) { + pm_runtime_put(sensor->sd.dev); + goto unlock; + } + } else { ret = ov2680_stream_disable(sensor); + pm_runtime_put(sensor->sd.dev); + } sensor->is_streaming = !!enable; @@ -519,7 +484,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, sensor->current_mode = mode; sensor->fmt = format->format; - sensor->mode_pending_changes = true; unlock: mutex_unlock(&sensor->lock); @@ -603,10 +567,6 @@ static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { .s_ctrl = ov2680_s_ctrl, }; -static const struct v4l2_subdev_core_ops ov2680_core_ops = { - .s_power = ov2680_s_power, -}; - static const struct v4l2_subdev_video_ops ov2680_video_ops = { .g_frame_interval = ov2680_s_g_frame_interval, .s_frame_interval = ov2680_s_g_frame_interval, @@ -623,7 +583,6 @@ static const struct v4l2_subdev_pad_ops ov2680_pad_ops = { }; static const struct v4l2_subdev_ops ov2680_subdev_ops = { - .core = &ov2680_core_ops, .video = &ov2680_video_ops, .pad = &ov2680_pad_ops, }; @@ -643,8 +602,6 @@ static int ov2680_mode_init(struct ov2680_dev *sensor) sensor->current_mode = init_mode; - sensor->mode_pending_changes = true; - return 0; } @@ -722,8 +679,6 @@ static int ov2680_check_id(struct ov2680_dev *sensor) u64 chip_id; int ret; - ov2680_power_on(sensor); - ret = cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, NULL); if (ret < 0) { dev_err(sensor->dev, "failed to read chip id\n"); @@ -800,18 +755,39 @@ static int ov2680_probe(struct i2c_client *client) mutex_init(&sensor->lock); - ret = ov2680_check_id(sensor); + /* + * Power up and verify the chip now, so that if runtime pm is + * disabled the chip is left on and streaming will work. + */ + ret = ov2680_power_on(sensor); if (ret < 0) goto lock_destroy; + ret = ov2680_check_id(sensor); + if (ret < 0) + goto err_powerdown; + + pm_runtime_set_active(&client->dev); + pm_runtime_get_noresume(&client->dev); + pm_runtime_enable(&client->dev); + ret = ov2680_v4l2_register(sensor); if (ret < 0) - goto lock_destroy; + goto err_pm_runtime; + + pm_runtime_set_autosuspend_delay(&client->dev, 1000); + pm_runtime_use_autosuspend(&client->dev); + pm_runtime_put_autosuspend(&client->dev); dev_info(dev, "ov2680 init correctly\n"); return 0; +err_pm_runtime: + pm_runtime_disable(&client->dev); + pm_runtime_put_noidle(&client->dev); +err_powerdown: + ov2680_power_off(sensor); lock_destroy: dev_err(dev, "ov2680 init fail: %d\n", ret); mutex_destroy(&sensor->lock); @@ -828,9 +804,18 @@ static void ov2680_remove(struct i2c_client *client) mutex_destroy(&sensor->lock); media_entity_cleanup(&sensor->sd.entity); v4l2_ctrl_handler_free(&sensor->ctrls.handler); + + /* + * Disable runtime PM. In case runtime PM is disabled in the kernel, + * make sure to turn power off manually. + */ + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) + ov2680_power_off(sensor); + pm_runtime_set_suspended(&client->dev); } -static int __maybe_unused ov2680_suspend(struct device *dev) +static int ov2680_suspend(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct ov2680_dev *sensor = to_ov2680_dev(sd); @@ -838,15 +823,19 @@ static int __maybe_unused ov2680_suspend(struct device *dev) if (sensor->is_streaming) ov2680_stream_disable(sensor); - return 0; + return ov2680_power_off(sensor); } -static int __maybe_unused ov2680_resume(struct device *dev) +static int ov2680_resume(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct ov2680_dev *sensor = to_ov2680_dev(sd); int ret; + ret = ov2680_power_on(sensor); + if (ret < 0) + goto stream_disable; + if (sensor->is_streaming) { ret = ov2680_stream_enable(sensor); if (ret < 0) @@ -862,9 +851,8 @@ static int __maybe_unused ov2680_resume(struct device *dev) return ret; } -static const struct dev_pm_ops ov2680_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov2680_suspend, ov2680_resume) -}; +static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, + NULL); static const struct of_device_id ov2680_dt_ids[] = { { .compatible = "ovti,ov2680" }, @@ -875,7 +863,7 @@ MODULE_DEVICE_TABLE(of, ov2680_dt_ids); static struct i2c_driver ov2680_i2c_driver = { .driver = { .name = "ov2680", - .pm = &ov2680_pm_ops, + .pm = pm_sleep_ptr(&ov2680_pm_ops), .of_match_table = ov2680_dt_ids, }, .probe = ov2680_probe, From patchwork Thu Aug 3 09:33:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339597 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 AC671C04A6A for ; Thu, 3 Aug 2023 09:35:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235112AbjHCJfl (ORCPT ); Thu, 3 Aug 2023 05:35:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235088AbjHCJfg (ORCPT ); Thu, 3 Aug 2023 05:35:36 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6467D3598 for ; Thu, 3 Aug 2023 02:34:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055255; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cObHkZ504KWlHQpDz8Tf2YqZrc4/61AxKkqb5T0wBaI=; b=eKJ2I22kRas9HOgwTswtQrOsOcvKqJ4oomxZ8hT74ofR39sFc3gjpwIjiXGhL07UtqEnEs jqITTcj9CQd+FvIBgkb/7LnEqyMSbdi9I7ZVWlJiqfmWQvqTOQEhib8fk49xg5GO9NCmf1 1GK7i1JmZ2C5HbbyuKL0ZCLqbtVJf5w= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-609-xAerU9l3MMKJud3ZnihYRQ-1; Thu, 03 Aug 2023 05:34:11 -0400 X-MC-Unique: xAerU9l3MMKJud3ZnihYRQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 13A0E185A78B; Thu, 3 Aug 2023 09:34:11 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id A1F4D2166B25; Thu, 3 Aug 2023 09:34:09 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 12/32] media: ov2680: Check for "powerdown" GPIO con-id before checking for "reset" GPIO con-id Date: Thu, 3 Aug 2023 11:33:27 +0200 Message-ID: <20230803093348.15679-13-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The datasheet of the OV2680 labels the single GPIO to put the sensor in powersaving mode as XSHUTDN aka shutdown, _not_ reset. This is important because some boards have standardized sensor connectors which allow connecting various sensor modules. These connectors have both reset and powerdown signals and the powerdown signal is routed to the OV2680's XSHUTDN pin. On x86/ACPI multiple Bay Trail, Cherry Trail, Sky Lake and Kaby Lake models have an OV2680 connected to the ISP2 / IPU3. On these devices the GPIOS are not described in DT instead the GPIOs are described with an Intel specific DSM which labels them as either powerdown or reset. Often this DSM returns both reset and powerdown pins even though the OV2680 has only 1 such pin. For the ov2680 driver to work on these devices it must use the GPIO with "powerdown" as con-id, matching the XSHUTDN name from the datasheet. As for why "powerdown" vs say "shutdown" the ACPI DSM -> con-id mapping code is shared, so we must use standardized names and currently all of the following sensor drivers already use "powerdown": adv7180, gc0310, isl7998x, ov02a10, ov2659, ov5640, ov5648, ov5670, ov5693, ov7670, ov772x, ov7740, ov8858, ov8865 and ov9650 . Where as the hi846 driver is the lonely standout using "shutdown". Try the "powerdown" con-id first to make things work, falling back to "reset" to keep existing DT setups working. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index bc0ca2927370..b912ae7a63da 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -97,7 +97,7 @@ struct ov2680_dev { u32 xvclk_freq; struct regulator_bulk_data supplies[OV2680_NUM_SUPPLIES]; - struct gpio_desc *reset_gpio; + struct gpio_desc *pwdn_gpio; struct mutex lock; /* protect members */ bool is_enabled; @@ -180,19 +180,19 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) static void ov2680_power_up(struct ov2680_dev *sensor) { - if (!sensor->reset_gpio) + if (!sensor->pwdn_gpio) return; - gpiod_set_value(sensor->reset_gpio, 0); + gpiod_set_value(sensor->pwdn_gpio, 0); usleep_range(5000, 10000); } static void ov2680_power_down(struct ov2680_dev *sensor) { - if (!sensor->reset_gpio) + if (!sensor->pwdn_gpio) return; - gpiod_set_value(sensor->reset_gpio, 1); + gpiod_set_value(sensor->pwdn_gpio, 1); usleep_range(5000, 10000); } @@ -336,7 +336,7 @@ static int ov2680_power_on(struct ov2680_dev *sensor) return ret; } - if (!sensor->reset_gpio) { + if (!sensor->pwdn_gpio) { ret = cci_write(sensor->regmap, OV2680_REG_SOFT_RESET, 0x01, NULL); if (ret != 0) { @@ -697,16 +697,27 @@ static int ov2680_check_id(struct ov2680_dev *sensor) static int ov2680_parse_dt(struct ov2680_dev *sensor) { struct device *dev = sensor->dev; + struct gpio_desc *gpio; int ret; - sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", - GPIOD_OUT_HIGH); - ret = PTR_ERR_OR_ZERO(sensor->reset_gpio); + /* + * The pin we want is named XSHUTDN in the datasheet. Linux sensor + * drivers have standardized on using "powerdown" as con-id name + * for powerdown or shutdown pins. Older DTB files use "reset", + * so fallback to that if there is no "powerdown" pin. + */ + gpio = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH); + if (!gpio) + gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + + ret = PTR_ERR_OR_ZERO(gpio); if (ret < 0) { dev_dbg(dev, "error while getting reset gpio: %d\n", ret); return ret; } + sensor->pwdn_gpio = gpio; + sensor->xvclk = devm_clk_get(dev, "xvclk"); if (IS_ERR(sensor->xvclk)) { dev_err(dev, "xvclk clock missing or invalid\n"); From patchwork Thu Aug 3 09:33:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339592 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 4BF0CC00528 for ; Thu, 3 Aug 2023 09:35:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235064AbjHCJfd (ORCPT ); Thu, 3 Aug 2023 05:35:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234112AbjHCJfc (ORCPT ); Thu, 3 Aug 2023 05:35:32 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 33DF3359A for ; Thu, 3 Aug 2023 02:34:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055256; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6Sh5AlyH1vXZe95z/Hl5DBWQk2sI0ipnCQ+0VvbPDFQ=; b=WH/ZAcig2T29HeaEOL1ZiNUN3JE5iZl+O98ImpPVut9llCowTCCFe2zIvTJTwmWYVZo3Qt QIVFTag1DWRc1bnf0S7EGhAaBpDJ7wHDYNb+U6Q+1WaGAqUfM/kcEG1uVIQkE5VHLGGgB8 6yoaYHHb1QWns3aFVreTL8wWUx+65eM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-67-cHhPbyLSPpSYESglYm4dhQ-1; Thu, 03 Aug 2023 05:34:13 -0400 X-MC-Unique: cHhPbyLSPpSYESglYm4dhQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AFC9083FC20; Thu, 3 Aug 2023 09:34:12 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 461BF2166B25; Thu, 3 Aug 2023 09:34:11 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 13/32] media: ov2680: Drop is_enabled flag Date: Thu, 3 Aug 2023 11:33:28 +0200 Message-ID: <20230803093348.15679-14-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org With runtime-pm it is guaranteed that ov2680_power_on() and ov2680_power_off() will always be called in a balanced way; and the is_enabled check in ov2680_s_ctrl() can be replaced by checking the runtime-suspend state. So there is no more need for the is_enabled flag, remove it. While at it also make sure that flip control changes while suspended still lead to the bayer-order getting updated so that get_fmt returns the correct bayer-order. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index b912ae7a63da..cf84701a6a5a 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -100,7 +100,6 @@ struct ov2680_dev { struct gpio_desc *pwdn_gpio; struct mutex lock; /* protect members */ - bool is_enabled; bool is_streaming; struct ov2680_ctrls ctrls; @@ -312,14 +311,9 @@ static int ov2680_stream_disable(struct ov2680_dev *sensor) static int ov2680_power_off(struct ov2680_dev *sensor) { - if (!sensor->is_enabled) - return 0; - clk_disable_unprepare(sensor->xvclk); ov2680_power_down(sensor); regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); - sensor->is_enabled = false; - return 0; } @@ -327,9 +321,6 @@ static int ov2680_power_on(struct ov2680_dev *sensor) { int ret; - if (sensor->is_enabled) - return 0; - ret = regulator_bulk_enable(OV2680_NUM_SUPPLIES, sensor->supplies); if (ret < 0) { dev_err(sensor->dev, "failed to enable regulators: %d\n", ret); @@ -353,8 +344,6 @@ static int ov2680_power_on(struct ov2680_dev *sensor) if (ret < 0) goto err_disable_regulators; - sensor->is_enabled = true; - return 0; err_disable_regulators: @@ -541,26 +530,37 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); struct ov2680_dev *sensor = to_ov2680_dev(sd); + int ret; - if (!sensor->is_enabled) + /* Only apply changes to the controls if the device is powered up */ + if (!pm_runtime_get_if_in_use(sensor->sd.dev)) { + ov2680_set_bayer_order(sensor, &sensor->fmt); return 0; + } switch (ctrl->id) { case V4L2_CID_GAIN: - return ov2680_gain_set(sensor, ctrl->val); + ret = ov2680_gain_set(sensor, ctrl->val); + break; case V4L2_CID_EXPOSURE: - return ov2680_exposure_set(sensor, ctrl->val); + ret = ov2680_exposure_set(sensor, ctrl->val); + break; case V4L2_CID_VFLIP: - return ov2680_set_vflip(sensor, ctrl->val); + ret = ov2680_set_vflip(sensor, ctrl->val); + break; case V4L2_CID_HFLIP: - return ov2680_set_hflip(sensor, ctrl->val); + ret = ov2680_set_hflip(sensor, ctrl->val); + break; case V4L2_CID_TEST_PATTERN: - return ov2680_test_pattern_set(sensor, ctrl->val); + ret = ov2680_test_pattern_set(sensor, ctrl->val); + break; default: + ret = -EINVAL; break; } - return -EINVAL; + pm_runtime_put(sensor->sd.dev); + return ret; } static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { From patchwork Thu Aug 3 09:33:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339593 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 60DECC0015E for ; Thu, 3 Aug 2023 09:35:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235090AbjHCJfh (ORCPT ); Thu, 3 Aug 2023 05:35:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234112AbjHCJff (ORCPT ); Thu, 3 Aug 2023 05:35:35 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FAF6359E for ; Thu, 3 Aug 2023 02:34:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055258; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6J1MAl5LFCsWVV56Ff0o/oZh8s2Y7U6u7psoOGTAky4=; b=Hj8VX+4N6KUvFkalep61KrlBZIcdBcN8cgX+lstSue5rlfkQlAhSAPr4kUzlcv+j1k8V4D 7RjO652ZjzINpY6aq6lv1Ba3jM10mlW0l3lSiS8tTSOH6Vgtcqx6u81u3kJX/agz87WaQb cUVfYgBZPshJ5psvjyvk8naG1F3gaBA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-260-zSwaiaN-Ovi1R1PaL5xOoA-1; Thu, 03 Aug 2023 05:34:14 -0400 X-MC-Unique: zSwaiaN-Ovi1R1PaL5xOoA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5658E858290; Thu, 3 Aug 2023 09:34:14 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id E16BE2166B26; Thu, 3 Aug 2023 09:34:12 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 14/32] media: ov2680: Add support for more clk setups Date: Thu, 3 Aug 2023 11:33:29 +0200 Message-ID: <20230803093348.15679-15-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org On ACPI systems the following 2 scenarios are possible: 1. The xvclk is fully controlled by ACPI powermanagement, so there is no "xvclk" for the driver to get (since it is abstracted away). In this case there will be a "clock-frequency" device property to tell the driver the xvclk rate. 2. There is a xvclk modelled in the clk framework for the driver, but the clk-generator may not be set to the right frequency yet. In this case there will also be a "clock-frequency" device property and the driver is expected to set the rate of the xvclk through this frequency through the clk framework. Handle both these scenarios by switching to devm_clk_get_optional() and checking for a "clock-frequency" device property. This is modelled after how the same issue was fixed for the ov8865 in commit 73dcffeb2ff9 ("media: i2c: Support 19.2MHz input clock in ov8865"). Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Reviewed-by: Tommaso Merciai Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index cf84701a6a5a..42be7b094d5d 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -698,6 +698,7 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) { struct device *dev = sensor->dev; struct gpio_desc *gpio; + unsigned int rate = 0; int ret; /* @@ -718,13 +719,34 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) sensor->pwdn_gpio = gpio; - sensor->xvclk = devm_clk_get(dev, "xvclk"); + sensor->xvclk = devm_clk_get_optional(dev, "xvclk"); if (IS_ERR(sensor->xvclk)) { dev_err(dev, "xvclk clock missing or invalid\n"); return PTR_ERR(sensor->xvclk); } - sensor->xvclk_freq = clk_get_rate(sensor->xvclk); + /* + * We could have either a 24MHz or 19.2MHz clock rate from either DT or + * ACPI... but we also need to support the weird IPU3 case which will + * have an external clock AND a clock-frequency property. Check for the + * clock-frequency property and if found, set that rate if we managed + * to acquire a clock. This should cover the ACPI case. If the system + * uses devicetree then the configured rate should already be set, so + * we can just read it. + */ + ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", + &rate); + if (ret && !sensor->xvclk) + return dev_err_probe(dev, ret, "invalid clock config\n"); + + if (!ret && sensor->xvclk) { + ret = clk_set_rate(sensor->xvclk, rate); + if (ret) + return dev_err_probe(dev, ret, + "failed to set clock rate\n"); + } + + sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk); if (sensor->xvclk_freq != OV2680_XVCLK_VALUE) { dev_err(dev, "wrong xvclk frequency %d HZ, expected: %d Hz\n", sensor->xvclk_freq, OV2680_XVCLK_VALUE); From patchwork Thu Aug 3 09:33:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339595 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 CF2BEC0015E for ; Thu, 3 Aug 2023 09:35:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235100AbjHCJfj (ORCPT ); Thu, 3 Aug 2023 05:35:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235065AbjHCJfg (ORCPT ); Thu, 3 Aug 2023 05:35:36 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6459C35A1 for ; Thu, 3 Aug 2023 02:34:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055259; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=G4YTzOo0M3PotVSepMhJjFw+ylIFtmOwiPYC6E5PT1Y=; b=eoM35BBtM1PX5IhwCeCIb+flUaqxC0cWGMOHrFb1UbkBGn0gYtubwzUFvbKEpA5JXdXN7X GJCo+cW+2IyCae6i15CgLxPQGE2xXH5w0/iJxM4+rl9jixMna2TweQhltVfJASkfRZY/49 aQF8j1JIgG4UL5CX9rFImVPrtyQew1c= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-104-UE2ToU79N_-xcQr1_G7iqQ-1; Thu, 03 Aug 2023 05:34:16 -0400 X-MC-Unique: UE2ToU79N_-xcQr1_G7iqQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F0E1B3803508; Thu, 3 Aug 2023 09:34:15 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 88C5C2166B25; Thu, 3 Aug 2023 09:34:14 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 15/32] media: ov2680: Add support for 19.2 MHz clock Date: Thu, 3 Aug 2023 11:33:30 +0200 Message-ID: <20230803093348.15679-16-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Most x86/ACPI boards use the ov2680 with a 19.2 MHz xvclk, rather then the expected 24MHz, add support for this. Compensate for the lower clk by setting a higher PLL multiplier of 69 when using 19.2 MHz vs the default multiplier of 55 for a 24MHz xvclk. Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 42be7b094d5d..a8c257f3bcd6 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -27,14 +27,13 @@ #include #include -#define OV2680_XVCLK_VALUE 24000000 - #define OV2680_CHIP_ID 0x2680 #define OV2680_REG_STREAM_CTRL CCI_REG8(0x0100) #define OV2680_REG_SOFT_RESET CCI_REG8(0x0103) #define OV2680_REG_CHIP_ID CCI_REG16(0x300a) +#define OV2680_REG_PLL_MULTIPLIER CCI_REG16(0x3081) #define OV2680_REG_EXPOSURE_PK CCI_REG24(0x3500) #define OV2680_REG_R_MANUAL CCI_REG8(0x3503) @@ -69,6 +68,21 @@ static const char * const ov2680_supply_name[] = { #define OV2680_NUM_SUPPLIES ARRAY_SIZE(ov2680_supply_name) +enum { + OV2680_19_2_MHZ, + OV2680_24_MHZ, +}; + +static const unsigned long ov2680_xvclk_freqs[] = { + [OV2680_19_2_MHZ] = 19200000, + [OV2680_24_MHZ] = 24000000, +}; + +static const u8 ov2680_pll_multipliers[] = { + [OV2680_19_2_MHZ] = 69, + [OV2680_24_MHZ] = 55, +}; + struct ov2680_mode_info { const char *name; enum ov2680_mode_id id; @@ -95,6 +109,7 @@ struct ov2680_dev { struct media_pad pad; struct clk *xvclk; u32 xvclk_freq; + u8 pll_mult; struct regulator_bulk_data supplies[OV2680_NUM_SUPPLIES]; struct gpio_desc *pwdn_gpio; @@ -284,6 +299,11 @@ static int ov2680_stream_enable(struct ov2680_dev *sensor) { int ret; + ret = cci_write(sensor->regmap, OV2680_REG_PLL_MULTIPLIER, + sensor->pll_mult, NULL); + if (ret < 0) + return ret; + ret = regmap_multi_reg_write(sensor->regmap, ov2680_mode_init_data.reg_data, ov2680_mode_init_data.reg_data_size); @@ -699,7 +719,7 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) struct device *dev = sensor->dev; struct gpio_desc *gpio; unsigned int rate = 0; - int ret; + int i, ret; /* * The pin we want is named XSHUTDN in the datasheet. Linux sensor @@ -747,12 +767,19 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) } sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk); - if (sensor->xvclk_freq != OV2680_XVCLK_VALUE) { - dev_err(dev, "wrong xvclk frequency %d HZ, expected: %d Hz\n", - sensor->xvclk_freq, OV2680_XVCLK_VALUE); - return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(ov2680_xvclk_freqs); i++) { + if (sensor->xvclk_freq == ov2680_xvclk_freqs[i]) + break; } + if (i == ARRAY_SIZE(ov2680_xvclk_freqs)) + return dev_err_probe(dev, -EINVAL, + "unsupported xvclk frequency %d Hz\n", + sensor->xvclk_freq); + + sensor->pll_mult = ov2680_pll_multipliers[i]; + return 0; } From patchwork Thu Aug 3 09:33:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339598 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 62749C0015E for ; Thu, 3 Aug 2023 09:36:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235131AbjHCJgt (ORCPT ); Thu, 3 Aug 2023 05:36:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33302 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235130AbjHCJgA (ORCPT ); Thu, 3 Aug 2023 05:36:00 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6DB9435A2 for ; Thu, 3 Aug 2023 02:34:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055259; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0NgLAKz9Yt7HtZ5vybpERWJr/SrAgRfg1hdXVwyplVw=; b=RfnGW16vEHdrfcnzpkYnaAWger1pMz6tTz3R9FjTIzAL0vdlOp7841N42og0X0RPWZa/z1 BkMv+3I0eORO4V/qOqWyn/GhK2BIngVxaCaQVymPKnzcCrf2sQucqbGT2nMZiZ/8e7CihK GrGRijNjePGd6qolq4D7AqYJIIfF0lY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-134-Clv5J6QQOsOq-Hz2TVPYJQ-1; Thu, 03 Aug 2023 05:34:18 -0400 X-MC-Unique: Clv5J6QQOsOq-Hz2TVPYJQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9417688D06C; Thu, 3 Aug 2023 09:34:17 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2F49C2166B25; Thu, 3 Aug 2023 09:34:16 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 16/32] media: ov2680: Wait for endpoint fwnode before continuing with probe() Date: Thu, 3 Aug 2023 11:33:31 +0200 Message-ID: <20230803093348.15679-17-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Defer probe() until the endpoint fwnode is available. This is necessary on ACPI platforms where the bridge code creating the fwnodes may also e.g. set the "clock-frequency" device property and add GPIO mappings. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- Changes in v4: - Only defer probe do not set v4l2_subdev.fwnode --- drivers/media/i2c/ov2680.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index a8c257f3bcd6..d4664581b49b 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -717,10 +717,22 @@ static int ov2680_check_id(struct ov2680_dev *sensor) static int ov2680_parse_dt(struct ov2680_dev *sensor) { struct device *dev = sensor->dev; + struct fwnode_handle *ep_fwnode; struct gpio_desc *gpio; unsigned int rate = 0; int i, ret; + /* + * Sometimes the fwnode graph is initialized by the bridge driver. + * Bridge drivers doing this may also add GPIO mappings, wait for this. + */ + ep_fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); + if (!ep_fwnode) + return dev_err_probe(dev, -EPROBE_DEFER, + "waiting for fwnode graph endpoint\n"); + + fwnode_handle_put(ep_fwnode); + /* * The pin we want is named XSHUTDN in the datasheet. Linux sensor * drivers have standardized on using "powerdown" as con-id name @@ -801,7 +813,7 @@ static int ov2680_probe(struct i2c_client *client) ret = ov2680_parse_dt(sensor); if (ret < 0) - return -EINVAL; + return ret; ret = ov2680_mode_init(sensor); if (ret < 0) From patchwork Thu Aug 3 09:33:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339609 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 6289AC0015E for ; Thu, 3 Aug 2023 09:37:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235205AbjHCJhH (ORCPT ); Thu, 3 Aug 2023 05:37:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233295AbjHCJgG (ORCPT ); Thu, 3 Aug 2023 05:36:06 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02CD635A4 for ; Thu, 3 Aug 2023 02:34:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=P6MghfuQ3kvRwZzjJtE4BMBz/wpQQTEaLj+aFpwysHk=; b=iytb09haCZZyhozSi+ESgxT63wUKHVFKE2JHxchq2r6ixpV+AbdVn1LXHtIqksdcZFOxQD tjmw2dWvbIDS8p6ZmFkNBlUEWR0IEqyWlNdnCnv5A2GfDKcpV5HOiIKEVD4ZCnrHF5M07z DHlf9VhHcQek5OVk8vpojcCgzdSqoz4= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-492-pRGWiDPXMkyc04aWLkzwMA-1; Thu, 03 Aug 2023 05:34:19 -0400 X-MC-Unique: pRGWiDPXMkyc04aWLkzwMA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 37CBC3C01C2E; Thu, 3 Aug 2023 09:34:19 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id C6CA32166B25; Thu, 3 Aug 2023 09:34:17 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 17/32] media: ov2680: Add support for ACPI enumeration Date: Thu, 3 Aug 2023 11:33:32 +0200 Message-ID: <20230803093348.15679-18-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add an acpi_match_table now that all the other bits necessary for ACPI support are in place. The OVTI prefix used for the ACPI-HID is used for various OmniVision sensors on many generations x86 tablets and laptops. The OVTI2680 HID specifically is used on multiple models spanning at least 4 different Intel CPU models (2 ISP2, 2 IPU3). Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko --- Changes in v5: - Add some notes to the commit message about the OVTI2680 HID --- drivers/media/i2c/ov2680.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index d4664581b49b..0adfacc70735 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -932,11 +932,18 @@ static const struct of_device_id ov2680_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, ov2680_dt_ids); +static const struct acpi_device_id ov2680_acpi_ids[] = { + { "OVTI2680" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(acpi, ov2680_acpi_ids); + static struct i2c_driver ov2680_i2c_driver = { .driver = { .name = "ov2680", .pm = pm_sleep_ptr(&ov2680_pm_ops), .of_match_table = ov2680_dt_ids, + .acpi_match_table = ov2680_acpi_ids, }, .probe = ov2680_probe, .remove = ov2680_remove, From patchwork Thu Aug 3 09:33:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339599 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 9E804C0015E for ; Thu, 3 Aug 2023 09:37:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235118AbjHCJhE (ORCPT ); Thu, 3 Aug 2023 05:37:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235072AbjHCJgF (ORCPT ); Thu, 3 Aug 2023 05:36:05 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3537635A6 for ; Thu, 3 Aug 2023 02:34:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055266; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KWOneAe5/BFrkh6Y4MUil5D8m/sbDn/E9+AOy0W0w0U=; b=f+PvSQ5Ct+m42EVb0aRM3aGoSQ633Gi6oO5vwZHAztFeqC7kK6obaH/bVKa6yIoVcquIVn mHJYoI2MSgTk6z+wXaxUBhvXgWQu9n+tlR2aUS/jn8m/G6IwxG3BMzMsBZo2KCgr6m7fFS sWw4lD1XIR1TY1gqTS/M7opFKQWpQMk= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-626-2E5hCNPDN5id794Lrvv8yQ-1; Thu, 03 Aug 2023 05:34:21 -0400 X-MC-Unique: 2E5hCNPDN5id794Lrvv8yQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D3F20380350F; Thu, 3 Aug 2023 09:34:20 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6A3DB2166B25; Thu, 3 Aug 2023 09:34:19 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 18/32] media: ov2680: Fix ov2680_enum_frame_interval() Date: Thu, 3 Aug 2023 11:33:33 +0200 Message-ID: <20230803093348.15679-19-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Fix and simplify ov2680_enum_frame_interval(), the index is not an index into ov2680_mode_data[], so using OV2680_MODE_MAX is wrong. Instead it is an index indexing the different framerates for the resolution specified in fie->width, fie->height. Note validating fie->which is not necessary this is already done by the v4l2-core. Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- Changes in v4: - Verify that the passed in which, width and height are valid --- drivers/media/i2c/ov2680.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 0adfacc70735..a83efd449993 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -527,21 +527,30 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd, return 0; } +static bool ov2680_valid_frame_size(struct v4l2_subdev_frame_interval_enum *fie) +{ + int i; + + for (i = 0; i < OV2680_MODE_MAX; i++) { + if (fie->width == ov2680_mode_data[i].width && + fie->height == ov2680_mode_data[i].height) + return true; + } + + return false; +} + static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_interval_enum *fie) { - struct v4l2_fract tpf; + struct ov2680_dev *sensor = to_ov2680_dev(sd); - if (fie->index >= OV2680_MODE_MAX || fie->width > OV2680_WIDTH_MAX || - fie->height > OV2680_HEIGHT_MAX || - fie->which > V4L2_SUBDEV_FORMAT_ACTIVE) + /* Only 1 framerate */ + if (fie->index || !ov2680_valid_frame_size(fie)) return -EINVAL; - tpf.denominator = OV2680_FRAME_RATE; - tpf.numerator = 1; - - fie->interval = tpf; + fie->interval = sensor->frame_interval; return 0; } From patchwork Thu Aug 3 09:33:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339600 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 48B17C04A6A for ; Thu, 3 Aug 2023 09:37:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235137AbjHCJhF (ORCPT ); Thu, 3 Aug 2023 05:37:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235136AbjHCJgF (ORCPT ); Thu, 3 Aug 2023 05:36:05 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF5CB35A5 for ; Thu, 3 Aug 2023 02:34:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055265; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OU0ELlj18DaO7z7eFjreRnwtZGmvkS2ThEX3kD1fe7I=; b=KgLrh8AvEmi0hZ7VVvfV9wWA3/F420rIdBKo0bUU7vOWnqFkiKGIyKdBX3US3+EqwPIQHB vT9P9qyIdQCR+8UD/BkqZ1QQiQnNVEXWiMULFwadU8RVv40uTJp8DroOJaXXBrH0+WLd9x 6ckXW9mKTT7T6TAtHMA9xRjYUBOEYgo= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-207--WfbfLPSPnqff240Uztyww-1; Thu, 03 Aug 2023 05:34:23 -0400 X-MC-Unique: -WfbfLPSPnqff240Uztyww-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 773C02A59578; Thu, 3 Aug 2023 09:34:22 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 11DB42166B25; Thu, 3 Aug 2023 09:34:20 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 19/32] media: ov2680: Annotate the per mode register setting lists Date: Thu, 3 Aug 2023 11:33:34 +0200 Message-ID: <20230803093348.15679-20-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Annotate the per mode register setting lists. This is a preparation patch for moving to calculating the per mode settings, allowing to set any mode through cropping. The annotations make it easier to see which registers are mode dependent and which are fixed. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 118 ++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index a83efd449993..e7d2e555e1c6 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -140,27 +140,117 @@ static const int ov2680_hv_flip_bayer_order[] = { }; static const struct reg_sequence ov2680_setting_30fps_QUXGA_800_600[] = { - {0x3086, 0x01}, {0x370a, 0x23}, {0x3808, 0x03}, {0x3809, 0x20}, - {0x380a, 0x02}, {0x380b, 0x58}, {0x380c, 0x06}, {0x380d, 0xac}, - {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, - {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, - {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, + /* Set PLL SP DIV to 1 for binning mode */ + {0x3086, 0x01}, + + /* Sensor control register 0x0a to 0x23 for binning mode */ + {0x370a, 0x23}, + + /* Set X and Y output size to 800x600 */ + {0x3808, 0x03}, + {0x3809, 0x20}, + {0x380a, 0x02}, + {0x380b, 0x58}, + + /* Set HTS + VTS to 1708x644 */ + {0x380c, 0x06}, + {0x380d, 0xac}, + {0x380e, 0x02}, + {0x380f, 0x84}, + + /* Set ISP WIN X and Y start to 4x4 */ + {0x3811, 0x04}, + {0x3813, 0x04}, + + /* Set X INC and Y INC for binning */ + {0x3814, 0x31}, + {0x3815, 0x31}, + + /* Initialize FORMAT1 to default/reset value (vflip disabled) */ + {0x3820, 0xc0}, + + /* Set black level compensation range to 0 - 3 (default 0 - 11) */ + {0x4008, 0x00}, + {0x4009, 0x03}, + + /* Set MIPI pclk period to 0x1e (default/reset is 0x18) */ + {0x4837, 0x1e}, + + /* Initialize exposure to 0x4ee (overridden by the ctrl, drop this */ + {0x3501, 0x4e}, + {0x3502, 0xe0}, + + /* R MANUAL set exposure and gain to manual (hw does not do auto) */ {0x3503, 0x03}, }; static const struct reg_sequence ov2680_setting_30fps_720P_1280_720[] = { - {0x3086, 0x00}, {0x3808, 0x05}, {0x3809, 0x00}, {0x380a, 0x02}, - {0x380b, 0xd0}, {0x380c, 0x06}, {0x380d, 0xa8}, {0x380e, 0x05}, - {0x380f, 0x0e}, {0x3811, 0x08}, {0x3813, 0x06}, {0x3814, 0x11}, - {0x3815, 0x11}, {0x3820, 0xc0}, {0x4008, 0x00}, + /* Set PLL SP DIV to 0 for not binning mode */ + {0x3086, 0x00}, + + /* Set X and Y output size to 1280x720 */ + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + + /* Set HTS + VTS to 1704x1294 */ + {0x380c, 0x06}, + {0x380d, 0xa8}, + {0x380e, 0x05}, + {0x380f, 0x0e}, + + /* Set ISP WIN X and Y start to 8x6 */ + {0x3811, 0x08}, + {0x3813, 0x06}, + + /* Set X INC and Y INC for non binning */ + {0x3814, 0x11}, + {0x3815, 0x11}, + + /* Initialize FORMAT1 to default/reset value (vflip disabled) */ + {0x3820, 0xc0}, + + /* Set backlight compensation range start to 0 */ + {0x4008, 0x00}, }; static const struct reg_sequence ov2680_setting_30fps_UXGA_1600_1200[] = { - {0x3086, 0x00}, {0x3501, 0x4e}, {0x3502, 0xe0}, {0x3808, 0x06}, - {0x3809, 0x40}, {0x380a, 0x04}, {0x380b, 0xb0}, {0x380c, 0x06}, - {0x380d, 0xa8}, {0x380e, 0x05}, {0x380f, 0x0e}, {0x3811, 0x00}, - {0x3813, 0x00}, {0x3814, 0x11}, {0x3815, 0x11}, {0x3820, 0xc0}, - {0x4008, 0x00}, {0x4837, 0x18} + /* Set PLL SP DIV to 0 for not binning mode */ + {0x3086, 0x00}, + + /* Initialize exposure to 0x4ee (overridden by the ctrl, drop this */ + {0x3501, 0x4e}, + {0x3502, 0xe0}, + + /* Set X and Y output size to 1600x1200 */ + {0x3808, 0x06}, + {0x3809, 0x40}, + {0x380a, 0x04}, + {0x380b, 0xb0}, + + /* Set HTS + VTS to 1704x1294 */ + {0x380c, 0x06}, + {0x380d, 0xa8}, + {0x380e, 0x05}, + {0x380f, 0x0e}, + + /* Set ISP WIN X and Y start to 0x0 */ + {0x3811, 0x00}, + {0x3813, 0x00}, + + /* Set X INC and Y INC for non binning */ + {0x3814, 0x11}, + {0x3815, 0x11}, + + /* Initialize FORMAT1 to default/reset value (vflip disabled) */ + {0x3820, 0xc0}, + + /* Set backlight compensation range start to 0 */ + {0x4008, 0x00}, + + /* Set MIPI pclk period to default/reset value of 0x18 */ + {0x4837, 0x18} }; static const struct ov2680_mode_info ov2680_mode_init_data = { From patchwork Thu Aug 3 09:33:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339610 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 79034C00528 for ; Thu, 3 Aug 2023 09:37:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235211AbjHCJhJ (ORCPT ); Thu, 3 Aug 2023 05:37:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235104AbjHCJgQ (ORCPT ); Thu, 3 Aug 2023 05:36:16 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB28635B5 for ; Thu, 3 Aug 2023 02:34:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055271; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uUprhVBja7nZeiW0CAnKUaW64QHkdPVI2IpjVXsFGuo=; b=H5uP+V0LQs7RKVdYDWEih1vsD1XA7cKpyg91Hofy4b3FeGQtDkJKKa8p3RS6qyCpTiMJSC MrU5jMwb3teRg3n5W4npXJt9/IMlmn2XQ9mBqAZID7Qb1Kxi1WwCCrtZ6rVU3kASY/W6ji 8+Cr+/4ofOL3xW5xbrmwXOy2u+00FFE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-573-mlTnI9MvN9OK0szWtD89kQ-1; Thu, 03 Aug 2023 05:34:24 -0400 X-MC-Unique: mlTnI9MvN9OK0szWtD89kQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 1FCED856F66; Thu, 3 Aug 2023 09:34:24 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id A9EA62166B25; Thu, 3 Aug 2023 09:34:22 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 20/32] media: ov2680: Add ov2680_mode struct Date: Thu, 3 Aug 2023 11:33:35 +0200 Message-ID: <20230803093348.15679-21-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add an ov2680_mode struct to group together mode related state. For now this only containst the v4l2_mbus_framefmt and the frame_interval. This is a preparation patch for moving to calculating the per mode settings, which will store more info in the new ov2680_mode struct. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index e7d2e555e1c6..76f97d053e45 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -101,6 +101,11 @@ struct ov2680_ctrls { struct v4l2_ctrl *test_pattern; }; +struct ov2680_mode { + struct v4l2_mbus_framefmt fmt; + struct v4l2_fract frame_interval; +}; + struct ov2680_dev { struct device *dev; struct regmap *regmap; @@ -118,8 +123,7 @@ struct ov2680_dev { bool is_streaming; struct ov2680_ctrls ctrls; - struct v4l2_mbus_framefmt fmt; - struct v4l2_fract frame_interval; + struct ov2680_mode mode; const struct ov2680_mode_info *current_mode; }; @@ -338,7 +342,7 @@ static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) if (ret < 0) return ret; - ov2680_set_bayer_order(sensor, &sensor->fmt); + ov2680_set_bayer_order(sensor, &sensor->mode.fmt); return 0; } @@ -354,7 +358,7 @@ static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) if (ret < 0) return ret; - ov2680_set_bayer_order(sensor, &sensor->fmt); + ov2680_set_bayer_order(sensor, &sensor->mode.fmt); return 0; } @@ -467,7 +471,7 @@ static int ov2680_s_g_frame_interval(struct v4l2_subdev *sd, struct ov2680_dev *sensor = to_ov2680_dev(sd); mutex_lock(&sensor->lock); - fi->interval = sensor->frame_interval; + fi->interval = sensor->mode.frame_interval; mutex_unlock(&sensor->lock); return 0; @@ -515,7 +519,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, if (code->pad != 0 || code->index != 0) return -EINVAL; - code->code = sensor->fmt.code; + code->code = sensor->mode.fmt.code; return 0; } @@ -536,7 +540,7 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, format->pad); } else { - fmt = &sensor->fmt; + fmt = &sensor->mode.fmt; } format->format = *fmt; @@ -582,7 +586,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, } sensor->current_mode = mode; - sensor->fmt = format->format; + sensor->mode.fmt = format->format; unlock: mutex_unlock(&sensor->lock); @@ -640,7 +644,7 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, if (fie->index || !ov2680_valid_frame_size(fie)) return -EINVAL; - fie->interval = sensor->frame_interval; + fie->interval = sensor->mode.frame_interval; return 0; } @@ -653,7 +657,7 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) /* Only apply changes to the controls if the device is powered up */ if (!pm_runtime_get_if_in_use(sensor->sd.dev)) { - ov2680_set_bayer_order(sensor, &sensor->fmt); + ov2680_set_bayer_order(sensor, &sensor->mode.fmt); return 0; } @@ -711,11 +715,11 @@ static int ov2680_mode_init(struct ov2680_dev *sensor) const struct ov2680_mode_info *init_mode; /* set initial mode */ - ov2680_fill_format(sensor, &sensor->fmt, + ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); - sensor->frame_interval.denominator = OV2680_FRAME_RATE; - sensor->frame_interval.numerator = 1; + sensor->mode.frame_interval.denominator = OV2680_FRAME_RATE; + sensor->mode.frame_interval.numerator = 1; init_mode = &ov2680_mode_init_data; From patchwork Thu Aug 3 09:33:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339612 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 E68E0C00528 for ; Thu, 3 Aug 2023 09:37:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235109AbjHCJhN (ORCPT ); Thu, 3 Aug 2023 05:37:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33322 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235139AbjHCJgR (ORCPT ); Thu, 3 Aug 2023 05:36:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4F3735B0 for ; Thu, 3 Aug 2023 02:34:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055269; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1yLiZDQY4dJFD3aJcbyYyYnyvguSbvVE31Ylk6aHR6w=; b=E6a4qSGi9Itb+uh5Ta8Z4NDDRpkLhICUJtrXA/3/XWXHqd17o8Urk/KeVMxZ8TaKjh1iTw 7coub1AVt8DV7SM+qE0Jf4TnsjBevSnly0VMEIOSdEavvYeeFyFXaVwo3duDkfwYuN5zZQ pnuITPypwD1ocDN7OjcqVYoNEmHs8XM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-50-Ia-bJXq_OQuPPyqbxhagWw-1; Thu, 03 Aug 2023 05:34:26 -0400 X-MC-Unique: Ia-bJXq_OQuPPyqbxhagWw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B6901800159; Thu, 3 Aug 2023 09:34:25 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 508882166B25; Thu, 3 Aug 2023 09:34:24 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 21/32] media: ov2680: Make setting the mode algorithm based Date: Thu, 3 Aug 2023 11:33:36 +0200 Message-ID: <20230803093348.15679-22-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Instead of using a long fixed register settings list for each resolution, calculate the register settings based on the requested width + height. This is based on atomisp-ov2680 commit 0611888592df ("media: atomisp: ov2680: Make setting the modes algorithm based"). This will allow future enhancements like adding hblank and vblank controls and adding selection support. This also adds properly programming the ISP window and setting the manual ISP window control bit in register 0x5708, this is necessary for the hflip and vflip conrols to work properly. Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- Changes in v4: - Make enum_frame_size() returned full-size + binned-/quarter-size, like the ov5693 code does --- drivers/media/i2c/ov2680.c | 334 +++++++++++++++++-------------------- 1 file changed, 157 insertions(+), 177 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 76f97d053e45..012b95f90c1d 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -38,27 +38,48 @@ #define OV2680_REG_EXPOSURE_PK CCI_REG24(0x3500) #define OV2680_REG_R_MANUAL CCI_REG8(0x3503) #define OV2680_REG_GAIN_PK CCI_REG16(0x350a) + +#define OV2680_REG_SENSOR_CTRL_0A CCI_REG8(0x370a) + +#define OV2680_REG_HORIZONTAL_START CCI_REG16(0x3800) +#define OV2680_REG_VERTICAL_START CCI_REG16(0x3802) +#define OV2680_REG_HORIZONTAL_END CCI_REG16(0x3804) +#define OV2680_REG_VERTICAL_END CCI_REG16(0x3806) +#define OV2680_REG_HORIZONTAL_OUTPUT_SIZE CCI_REG16(0x3808) +#define OV2680_REG_VERTICAL_OUTPUT_SIZE CCI_REG16(0x380a) #define OV2680_REG_TIMING_HTS CCI_REG16(0x380c) #define OV2680_REG_TIMING_VTS CCI_REG16(0x380e) +#define OV2680_REG_ISP_X_WIN CCI_REG16(0x3810) +#define OV2680_REG_ISP_Y_WIN CCI_REG16(0x3812) +#define OV2680_REG_X_INC CCI_REG8(0x3814) +#define OV2680_REG_Y_INC CCI_REG8(0x3815) #define OV2680_REG_FORMAT1 CCI_REG8(0x3820) #define OV2680_REG_FORMAT2 CCI_REG8(0x3821) #define OV2680_REG_ISP_CTRL00 CCI_REG8(0x5080) +#define OV2680_REG_X_WIN CCI_REG16(0x5704) +#define OV2680_REG_Y_WIN CCI_REG16(0x5706) + #define OV2680_FRAME_RATE 30 -#define OV2680_WIDTH_MAX 1600 -#define OV2680_HEIGHT_MAX 1200 +#define OV2680_NATIVE_WIDTH 1616 +#define OV2680_NATIVE_HEIGHT 1216 +#define OV2680_ACTIVE_WIDTH 1600 +#define OV2680_ACTIVE_HEIGHT 1200 + +/* 66MHz pixel clock: 66MHz / 1704 * 1294 = 30fps */ +#define OV2680_PIXELS_PER_LINE 1704 +#define OV2680_LINES_PER_FRAME 1294 + +/* If possible send 16 extra rows / lines to the ISP as padding */ +#define OV2680_END_MARGIN 16 #define OV2680_DEFAULT_WIDTH 800 #define OV2680_DEFAULT_HEIGHT 600 -enum ov2680_mode_id { - OV2680_MODE_QUXGA_800_600, - OV2680_MODE_720P_1280_720, - OV2680_MODE_UXGA_1600_1200, - OV2680_MODE_MAX, -}; +/* For enum_frame_size() full-size + binned-/quarter-size */ +#define OV2680_FRAME_SIZES 2 static const char * const ov2680_supply_name[] = { "DOVDD", @@ -83,15 +104,6 @@ static const u8 ov2680_pll_multipliers[] = { [OV2680_24_MHZ] = 55, }; -struct ov2680_mode_info { - const char *name; - enum ov2680_mode_id id; - u32 width; - u32 height; - const struct reg_sequence *reg_data; - u32 reg_data_size; -}; - struct ov2680_ctrls { struct v4l2_ctrl_handler handler; struct v4l2_ctrl *exposure; @@ -104,6 +116,15 @@ struct ov2680_ctrls { struct ov2680_mode { struct v4l2_mbus_framefmt fmt; struct v4l2_fract frame_interval; + bool binning; + u16 h_start; + u16 v_start; + u16 h_end; + u16 v_end; + u16 h_output_size; + u16 v_output_size; + u16 hts; + u16 vts; }; struct ov2680_dev { @@ -124,8 +145,6 @@ struct ov2680_dev { struct ov2680_ctrls ctrls; struct ov2680_mode mode; - - const struct ov2680_mode_info *current_mode; }; static const char * const test_pattern_menu[] = { @@ -143,136 +162,19 @@ static const int ov2680_hv_flip_bayer_order[] = { MEDIA_BUS_FMT_SRGGB10_1X10, }; -static const struct reg_sequence ov2680_setting_30fps_QUXGA_800_600[] = { - /* Set PLL SP DIV to 1 for binning mode */ - {0x3086, 0x01}, - - /* Sensor control register 0x0a to 0x23 for binning mode */ - {0x370a, 0x23}, - - /* Set X and Y output size to 800x600 */ - {0x3808, 0x03}, - {0x3809, 0x20}, - {0x380a, 0x02}, - {0x380b, 0x58}, - - /* Set HTS + VTS to 1708x644 */ - {0x380c, 0x06}, - {0x380d, 0xac}, - {0x380e, 0x02}, - {0x380f, 0x84}, - - /* Set ISP WIN X and Y start to 4x4 */ - {0x3811, 0x04}, - {0x3813, 0x04}, - - /* Set X INC and Y INC for binning */ - {0x3814, 0x31}, - {0x3815, 0x31}, - - /* Initialize FORMAT1 to default/reset value (vflip disabled) */ - {0x3820, 0xc0}, +static const struct reg_sequence ov2680_global_setting[] = { + /* R MANUAL set exposure and gain to manual (hw does not do auto) */ + {0x3503, 0x03}, /* Set black level compensation range to 0 - 3 (default 0 - 11) */ {0x4008, 0x00}, {0x4009, 0x03}, - /* Set MIPI pclk period to 0x1e (default/reset is 0x18) */ - {0x4837, 0x1e}, - - /* Initialize exposure to 0x4ee (overridden by the ctrl, drop this */ - {0x3501, 0x4e}, - {0x3502, 0xe0}, - - /* R MANUAL set exposure and gain to manual (hw does not do auto) */ - {0x3503, 0x03}, -}; - -static const struct reg_sequence ov2680_setting_30fps_720P_1280_720[] = { - /* Set PLL SP DIV to 0 for not binning mode */ - {0x3086, 0x00}, - - /* Set X and Y output size to 1280x720 */ - {0x3808, 0x05}, - {0x3809, 0x00}, - {0x380a, 0x02}, - {0x380b, 0xd0}, - - /* Set HTS + VTS to 1704x1294 */ - {0x380c, 0x06}, - {0x380d, 0xa8}, - {0x380e, 0x05}, - {0x380f, 0x0e}, - - /* Set ISP WIN X and Y start to 8x6 */ - {0x3811, 0x08}, - {0x3813, 0x06}, - - /* Set X INC and Y INC for non binning */ - {0x3814, 0x11}, - {0x3815, 0x11}, - - /* Initialize FORMAT1 to default/reset value (vflip disabled) */ - {0x3820, 0xc0}, - - /* Set backlight compensation range start to 0 */ - {0x4008, 0x00}, -}; - -static const struct reg_sequence ov2680_setting_30fps_UXGA_1600_1200[] = { - /* Set PLL SP DIV to 0 for not binning mode */ - {0x3086, 0x00}, - - /* Initialize exposure to 0x4ee (overridden by the ctrl, drop this */ - {0x3501, 0x4e}, - {0x3502, 0xe0}, - - /* Set X and Y output size to 1600x1200 */ - {0x3808, 0x06}, - {0x3809, 0x40}, - {0x380a, 0x04}, - {0x380b, 0xb0}, - - /* Set HTS + VTS to 1704x1294 */ - {0x380c, 0x06}, - {0x380d, 0xa8}, - {0x380e, 0x05}, - {0x380f, 0x0e}, - - /* Set ISP WIN X and Y start to 0x0 */ - {0x3811, 0x00}, - {0x3813, 0x00}, - - /* Set X INC and Y INC for non binning */ - {0x3814, 0x11}, - {0x3815, 0x11}, - - /* Initialize FORMAT1 to default/reset value (vflip disabled) */ - {0x3820, 0xc0}, - - /* Set backlight compensation range start to 0 */ - {0x4008, 0x00}, - - /* Set MIPI pclk period to default/reset value of 0x18 */ - {0x4837, 0x18} -}; - -static const struct ov2680_mode_info ov2680_mode_init_data = { - "mode_quxga_800_600", OV2680_MODE_QUXGA_800_600, 800, 600, - ov2680_setting_30fps_QUXGA_800_600, - ARRAY_SIZE(ov2680_setting_30fps_QUXGA_800_600), -}; - -static const struct ov2680_mode_info ov2680_mode_data[OV2680_MODE_MAX] = { - {"mode_quxga_800_600", OV2680_MODE_QUXGA_800_600, - 800, 600, ov2680_setting_30fps_QUXGA_800_600, - ARRAY_SIZE(ov2680_setting_30fps_QUXGA_800_600)}, - {"mode_720p_1280_720", OV2680_MODE_720P_1280_720, - 1280, 720, ov2680_setting_30fps_720P_1280_720, - ARRAY_SIZE(ov2680_setting_30fps_720P_1280_720)}, - {"mode_uxga_1600_1200", OV2680_MODE_UXGA_1600_1200, - 1600, 1200, ov2680_setting_30fps_UXGA_1600_1200, - ARRAY_SIZE(ov2680_setting_30fps_UXGA_1600_1200)}, + /* + * Window CONTROL 0x00 -> 0x01, enable manual window control, + * this is necessary for full size flip and mirror support. + */ + {0x5708, 0x01}, }; static struct ov2680_dev *to_ov2680_dev(struct v4l2_subdev *sd) @@ -330,6 +232,85 @@ static void ov2680_fill_format(struct ov2680_dev *sensor, ov2680_set_bayer_order(sensor, fmt); } +static void ov2680_calc_mode(struct ov2680_dev *sensor) +{ + int width = sensor->mode.fmt.width; + int height = sensor->mode.fmt.height; + int orig_width = width; + int orig_height = height; + + if (width <= (OV2680_NATIVE_WIDTH / 2) && + height <= (OV2680_NATIVE_HEIGHT / 2)) { + sensor->mode.binning = true; + width *= 2; + height *= 2; + } else { + sensor->mode.binning = false; + } + + sensor->mode.h_start = ((OV2680_NATIVE_WIDTH - width) / 2) & ~1; + sensor->mode.v_start = ((OV2680_NATIVE_HEIGHT - height) / 2) & ~1; + sensor->mode.h_end = + min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1, + OV2680_NATIVE_WIDTH - 1); + sensor->mode.v_end = + min(sensor->mode.v_start + height + OV2680_END_MARGIN - 1, + OV2680_NATIVE_HEIGHT - 1); + sensor->mode.h_output_size = orig_width; + sensor->mode.v_output_size = orig_height; + sensor->mode.hts = OV2680_PIXELS_PER_LINE; + sensor->mode.vts = OV2680_LINES_PER_FRAME; +} + +static int ov2680_set_mode(struct ov2680_dev *sensor) +{ + u8 sensor_ctrl_0a, inc, fmt1, fmt2; + int ret = 0; + + if (sensor->mode.binning) { + sensor_ctrl_0a = 0x23; + inc = 0x31; + fmt1 = 0xc2; + fmt2 = 0x01; + } else { + sensor_ctrl_0a = 0x21; + inc = 0x11; + fmt1 = 0xc0; + fmt2 = 0x00; + } + + cci_write(sensor->regmap, OV2680_REG_SENSOR_CTRL_0A, + sensor_ctrl_0a, &ret); + cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_START, + sensor->mode.h_start, &ret); + cci_write(sensor->regmap, OV2680_REG_VERTICAL_START, + sensor->mode.v_start, &ret); + cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_END, + sensor->mode.h_end, &ret); + cci_write(sensor->regmap, OV2680_REG_VERTICAL_END, + sensor->mode.v_end, &ret); + cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_OUTPUT_SIZE, + sensor->mode.h_output_size, &ret); + cci_write(sensor->regmap, OV2680_REG_VERTICAL_OUTPUT_SIZE, + sensor->mode.v_output_size, &ret); + cci_write(sensor->regmap, OV2680_REG_TIMING_HTS, + sensor->mode.hts, &ret); + cci_write(sensor->regmap, OV2680_REG_TIMING_VTS, + sensor->mode.vts, &ret); + cci_write(sensor->regmap, OV2680_REG_ISP_X_WIN, 0, &ret); + cci_write(sensor->regmap, OV2680_REG_ISP_Y_WIN, 0, &ret); + cci_write(sensor->regmap, OV2680_REG_X_INC, inc, &ret); + cci_write(sensor->regmap, OV2680_REG_Y_INC, inc, &ret); + cci_write(sensor->regmap, OV2680_REG_X_WIN, + sensor->mode.h_output_size, &ret); + cci_write(sensor->regmap, OV2680_REG_Y_WIN, + sensor->mode.v_output_size, &ret); + cci_write(sensor->regmap, OV2680_REG_FORMAT1, fmt1, &ret); + cci_write(sensor->regmap, OV2680_REG_FORMAT2, fmt2, &ret); + + return ret; +} + static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) { int ret; @@ -399,14 +380,12 @@ static int ov2680_stream_enable(struct ov2680_dev *sensor) return ret; ret = regmap_multi_reg_write(sensor->regmap, - ov2680_mode_init_data.reg_data, - ov2680_mode_init_data.reg_data_size); + ov2680_global_setting, + ARRAY_SIZE(ov2680_global_setting)); if (ret < 0) return ret; - ret = regmap_multi_reg_write(sensor->regmap, - sensor->current_mode->reg_data, - sensor->current_mode->reg_data_size); + ret = ov2680_set_mode(sensor); if (ret < 0) return ret; @@ -556,21 +535,18 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, { struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *try_fmt; - const struct ov2680_mode_info *mode; + unsigned int width, height; int ret = 0; if (format->pad != 0) return -EINVAL; - mode = v4l2_find_nearest_size(ov2680_mode_data, - ARRAY_SIZE(ov2680_mode_data), - width, height, - format->format.width, - format->format.height); - if (!mode) - return -EINVAL; + width = min_t(unsigned int, ALIGN(format->format.width, 2), + OV2680_NATIVE_WIDTH); + height = min_t(unsigned int, ALIGN(format->format.height, 2), + OV2680_NATIVE_HEIGHT); - ov2680_fill_format(sensor, &format->format, mode->width, mode->height); + ov2680_fill_format(sensor, &format->format, width, height); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); @@ -585,8 +561,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, goto unlock; } - sensor->current_mode = mode; sensor->mode.fmt = format->format; + ov2680_calc_mode(sensor); unlock: mutex_unlock(&sensor->lock); @@ -608,26 +584,35 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { - int index = fse->index; - - if (index >= OV2680_MODE_MAX || index < 0) + if (fse->index >= OV2680_FRAME_SIZES) return -EINVAL; - fse->min_width = ov2680_mode_data[index].width; - fse->min_height = ov2680_mode_data[index].height; - fse->max_width = ov2680_mode_data[index].width; - fse->max_height = ov2680_mode_data[index].height; + fse->min_width = OV2680_ACTIVE_WIDTH / (fse->index + 1); + fse->min_height = OV2680_ACTIVE_HEIGHT / (fse->index + 1); + fse->max_width = fse->min_width; + fse->max_height = fse->min_height; return 0; } -static bool ov2680_valid_frame_size(struct v4l2_subdev_frame_interval_enum *fie) +static bool ov2680_valid_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_interval_enum *fie) { + struct v4l2_subdev_frame_size_enum fse = { + .pad = fie->pad, + .which = fie->which, + }; int i; - for (i = 0; i < OV2680_MODE_MAX; i++) { - if (fie->width == ov2680_mode_data[i].width && - fie->height == ov2680_mode_data[i].height) + for (i = 0; i < OV2680_FRAME_SIZES; i++) { + fse.index = i; + + if (ov2680_enum_frame_size(sd, sd_state, &fse)) + return false; + + if (fie->width == fse.min_width && + fie->height == fse.min_height) return true; } @@ -641,7 +626,7 @@ static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, struct ov2680_dev *sensor = to_ov2680_dev(sd); /* Only 1 framerate */ - if (fie->index || !ov2680_valid_frame_size(fie)) + if (fie->index || !ov2680_valid_frame_size(sd, sd_state, fie)) return -EINVAL; fie->interval = sensor->mode.frame_interval; @@ -712,19 +697,14 @@ static const struct v4l2_subdev_ops ov2680_subdev_ops = { static int ov2680_mode_init(struct ov2680_dev *sensor) { - const struct ov2680_mode_info *init_mode; - /* set initial mode */ ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); + ov2680_calc_mode(sensor); sensor->mode.frame_interval.denominator = OV2680_FRAME_RATE; sensor->mode.frame_interval.numerator = 1; - init_mode = &ov2680_mode_init_data; - - sensor->current_mode = init_mode; - return 0; } From patchwork Thu Aug 3 09:33:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339613 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 F1F91C0015E for ; Thu, 3 Aug 2023 09:37:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235218AbjHCJhP (ORCPT ); Thu, 3 Aug 2023 05:37:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33324 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235140AbjHCJgR (ORCPT ); Thu, 3 Aug 2023 05:36:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E70CB35BE for ; Thu, 3 Aug 2023 02:34:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055275; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EcDyRHvJxga23N24g7zZoepisVmaaImy82FpCV8nah8=; b=OOm3smgKuviNinvur3lyLgJzzzyt+9+T3vLivQqMFLoZGVECtN1TaC9PzN4cPzqe0iKiZ2 N28YX/erVSuHxqOjd6OmGxu/FXMBZs+3QxAFv7b0m5M2PaSH9qQ8XKFDuND5/1RAhaKMt6 5NA1zptOmIA1hcDpI6SCooUv8rWzZCU= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-126-u9cfM3OfP6OqbhXwAvE3xg-1; Thu, 03 Aug 2023 05:34:28 -0400 X-MC-Unique: u9cfM3OfP6OqbhXwAvE3xg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5CE8B380350D; Thu, 3 Aug 2023 09:34:27 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id E9A6C2166B25; Thu, 3 Aug 2023 09:34:25 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 22/32] media: ov2680: Add an __ov2680_get_pad_format() helper function Date: Thu, 3 Aug 2023 11:33:37 +0200 Message-ID: <20230803093348.15679-23-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add an __ov2680_get_pad_format() helper function. This is a preparation patch for adding selections support. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 012b95f90c1d..87c4c5ea47c9 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -220,6 +220,18 @@ static void ov2680_set_bayer_order(struct ov2680_dev *sensor, fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; } +static struct v4l2_mbus_framefmt * +__ov2680_get_pad_format(struct ov2680_dev *sensor, + struct v4l2_subdev_state *state, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_format(&sensor->sd, state, pad); + + return &sensor->mode.fmt; +} + static void ov2680_fill_format(struct ov2680_dev *sensor, struct v4l2_mbus_framefmt *fmt, unsigned int width, unsigned int height) @@ -508,22 +520,16 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct v4l2_mbus_framefmt *fmt = NULL; + struct v4l2_mbus_framefmt *fmt; if (format->pad != 0) return -EINVAL; + fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, + format->which); + mutex_lock(&sensor->lock); - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, - format->pad); - } else { - fmt = &sensor->mode.fmt; - } - format->format = *fmt; - mutex_unlock(&sensor->lock); return 0; From patchwork Thu Aug 3 09:33:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339611 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 5FE93C0015E for ; Thu, 3 Aug 2023 09:37:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235104AbjHCJhL (ORCPT ); Thu, 3 Aug 2023 05:37:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235138AbjHCJgR (ORCPT ); Thu, 3 Aug 2023 05:36:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BECB135B7 for ; Thu, 3 Aug 2023 02:34:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055273; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e/4G+Iar7zAzMOaOjmTmeuOnrpmRWKwrPGzL8rR9lfw=; b=Ur15C8XTyna68mhMM4mMtJBF3o5Cq11W7O8q1uptgA46vXUHELi2CSIRs0vqB+Rq5LalAx IBhdW9cWqlacqDjgSxPpzSi7pYF9N9HT1h/fqr1zTjba18dPVw5cXFqQ5x8ExOnBInekxO 90RzqbkdBjqNxIkU3YlmSbDvAGZ7Ncc= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-140-J2KisxYqMnuTxzS-75j8tg-1; Thu, 03 Aug 2023 05:34:29 -0400 X-MC-Unique: J2KisxYqMnuTxzS-75j8tg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 094A5101A54E; Thu, 3 Aug 2023 09:34:29 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8F8CD2166B25; Thu, 3 Aug 2023 09:34:27 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 23/32] media: ov2680: Implement selection support Date: Thu, 3 Aug 2023 11:33:38 +0200 Message-ID: <20230803093348.15679-24-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement selection support. Modelled after ov5693 selection support, but allow setting sizes smaller than crop-size through set_fmt() since that was already allowed. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- Changes in v4: - Make enum_frame_size() take the crop target into account Changes in v2: - Use clamp_val() instead of clamp() / clamp_t() --- drivers/media/i2c/ov2680.c | 153 ++++++++++++++++++++++++++++++++++--- 1 file changed, 141 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 87c4c5ea47c9..ecd99e6669bd 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -65,8 +65,14 @@ #define OV2680_NATIVE_WIDTH 1616 #define OV2680_NATIVE_HEIGHT 1216 +#define OV2680_NATIVE_START_LEFT 0 +#define OV2680_NATIVE_START_TOP 0 #define OV2680_ACTIVE_WIDTH 1600 #define OV2680_ACTIVE_HEIGHT 1200 +#define OV2680_ACTIVE_START_LEFT 8 +#define OV2680_ACTIVE_START_TOP 8 +#define OV2680_MIN_CROP_WIDTH 2 +#define OV2680_MIN_CROP_HEIGHT 2 /* 66MHz pixel clock: 66MHz / 1704 * 1294 = 30fps */ #define OV2680_PIXELS_PER_LINE 1704 @@ -114,6 +120,7 @@ struct ov2680_ctrls { }; struct ov2680_mode { + struct v4l2_rect crop; struct v4l2_mbus_framefmt fmt; struct v4l2_fract frame_interval; bool binning; @@ -147,6 +154,13 @@ struct ov2680_dev { struct ov2680_mode mode; }; +static const struct v4l2_rect ov2680_default_crop = { + .left = OV2680_ACTIVE_START_LEFT, + .top = OV2680_ACTIVE_START_TOP, + .width = OV2680_ACTIVE_WIDTH, + .height = OV2680_ACTIVE_HEIGHT, +}; + static const char * const test_pattern_menu[] = { "Disabled", "Color Bars", @@ -232,6 +246,18 @@ __ov2680_get_pad_format(struct ov2680_dev *sensor, return &sensor->mode.fmt; } +static struct v4l2_rect * +__ov2680_get_pad_crop(struct ov2680_dev *sensor, + struct v4l2_subdev_state *state, + unsigned int pad, + enum v4l2_subdev_format_whence which) +{ + if (which == V4L2_SUBDEV_FORMAT_TRY) + return v4l2_subdev_get_try_crop(&sensor->sd, state, pad); + + return &sensor->mode.crop; +} + static void ov2680_fill_format(struct ov2680_dev *sensor, struct v4l2_mbus_framefmt *fmt, unsigned int width, unsigned int height) @@ -251,8 +277,8 @@ static void ov2680_calc_mode(struct ov2680_dev *sensor) int orig_width = width; int orig_height = height; - if (width <= (OV2680_NATIVE_WIDTH / 2) && - height <= (OV2680_NATIVE_HEIGHT / 2)) { + if (width <= (sensor->mode.crop.width / 2) && + height <= (sensor->mode.crop.height / 2)) { sensor->mode.binning = true; width *= 2; height *= 2; @@ -260,8 +286,10 @@ static void ov2680_calc_mode(struct ov2680_dev *sensor) sensor->mode.binning = false; } - sensor->mode.h_start = ((OV2680_NATIVE_WIDTH - width) / 2) & ~1; - sensor->mode.v_start = ((OV2680_NATIVE_HEIGHT - height) / 2) & ~1; + sensor->mode.h_start = (sensor->mode.crop.left + + (sensor->mode.crop.width - width) / 2) & ~1; + sensor->mode.v_start = (sensor->mode.crop.top + + (sensor->mode.crop.height - height) / 2) & ~1; sensor->mode.h_end = min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1, OV2680_NATIVE_WIDTH - 1); @@ -541,16 +569,21 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, { struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *try_fmt; + const struct v4l2_rect *crop; unsigned int width, height; int ret = 0; if (format->pad != 0) return -EINVAL; - width = min_t(unsigned int, ALIGN(format->format.width, 2), - OV2680_NATIVE_WIDTH); - height = min_t(unsigned int, ALIGN(format->format.height, 2), - OV2680_NATIVE_HEIGHT); + crop = __ov2680_get_pad_crop(sensor, sd_state, format->pad, + format->which); + + /* Limit set_fmt max size to crop width / height */ + width = clamp_val(ALIGN(format->format.width, 2), + OV2680_MIN_CROP_WIDTH, crop->width); + height = clamp_val(ALIGN(format->format.height, 2), + OV2680_MIN_CROP_HEIGHT, crop->height); ov2680_fill_format(sensor, &format->format, width, height); @@ -576,11 +609,97 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, return ret; } +static int ov2680_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ov2680_dev *sensor = to_ov2680_dev(sd); + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + mutex_lock(&sensor->lock); + sel->r = *__ov2680_get_pad_crop(sensor, state, sel->pad, + sel->which); + mutex_unlock(&sensor->lock); + break; + case V4L2_SEL_TGT_NATIVE_SIZE: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = OV2680_NATIVE_WIDTH; + sel->r.height = OV2680_NATIVE_HEIGHT; + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r = ov2680_default_crop; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ov2680_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ov2680_dev *sensor = to_ov2680_dev(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + struct v4l2_rect rect; + + if (sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + /* + * Clamp the boundaries of the crop rectangle to the size of the sensor + * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't + * disrupted. + */ + rect.left = clamp_val(ALIGN(sel->r.left, 2), + OV2680_NATIVE_START_LEFT, OV2680_NATIVE_WIDTH); + rect.top = clamp_val(ALIGN(sel->r.top, 2), + OV2680_NATIVE_START_TOP, OV2680_NATIVE_HEIGHT); + rect.width = clamp_val(ALIGN(sel->r.width, 2), + OV2680_MIN_CROP_WIDTH, OV2680_NATIVE_WIDTH); + rect.height = clamp_val(ALIGN(sel->r.height, 2), + OV2680_MIN_CROP_HEIGHT, OV2680_NATIVE_HEIGHT); + + /* Make sure the crop rectangle isn't outside the bounds of the array */ + rect.width = min_t(unsigned int, rect.width, + OV2680_NATIVE_WIDTH - rect.left); + rect.height = min_t(unsigned int, rect.height, + OV2680_NATIVE_HEIGHT - rect.top); + + crop = __ov2680_get_pad_crop(sensor, state, sel->pad, sel->which); + + mutex_lock(&sensor->lock); + if (rect.width != crop->width || rect.height != crop->height) { + /* + * Reset the output image size if the crop rectangle size has + * been modified. + */ + format = __ov2680_get_pad_format(sensor, state, sel->pad, + sel->which); + format->width = rect.width; + format->height = rect.height; + } + + *crop = rect; + mutex_unlock(&sensor->lock); + + sel->r = rect; + + return 0; +} + static int ov2680_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { struct ov2680_dev *sensor = to_ov2680_dev(sd); + sd_state->pads[0].try_crop = ov2680_default_crop; + ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt, OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); return 0; @@ -590,11 +709,18 @@ static int ov2680_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_frame_size_enum *fse) { + struct ov2680_dev *sensor = to_ov2680_dev(sd); + struct v4l2_rect *crop; + if (fse->index >= OV2680_FRAME_SIZES) return -EINVAL; - fse->min_width = OV2680_ACTIVE_WIDTH / (fse->index + 1); - fse->min_height = OV2680_ACTIVE_HEIGHT / (fse->index + 1); + crop = __ov2680_get_pad_crop(sensor, sd_state, fse->pad, fse->which); + if (!crop) + return -EINVAL; + + fse->min_width = crop->width / (fse->index + 1); + fse->min_height = crop->height / (fse->index + 1); fse->max_width = fse->min_width; fse->max_height = fse->min_height; @@ -690,10 +816,12 @@ static const struct v4l2_subdev_video_ops ov2680_video_ops = { static const struct v4l2_subdev_pad_ops ov2680_pad_ops = { .init_cfg = ov2680_init_cfg, .enum_mbus_code = ov2680_enum_mbus_code, - .get_fmt = ov2680_get_fmt, - .set_fmt = ov2680_set_fmt, .enum_frame_size = ov2680_enum_frame_size, .enum_frame_interval = ov2680_enum_frame_interval, + .get_fmt = ov2680_get_fmt, + .set_fmt = ov2680_set_fmt, + .get_selection = ov2680_get_selection, + .set_selection = ov2680_set_selection, }; static const struct v4l2_subdev_ops ov2680_subdev_ops = { @@ -704,6 +832,7 @@ static const struct v4l2_subdev_ops ov2680_subdev_ops = { static int ov2680_mode_init(struct ov2680_dev *sensor) { /* set initial mode */ + sensor->mode.crop = ov2680_default_crop; ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); ov2680_calc_mode(sensor); From patchwork Thu Aug 3 09:33:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339616 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 6533CC00528 for ; Thu, 3 Aug 2023 09:37:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235186AbjHCJhV (ORCPT ); Thu, 3 Aug 2023 05:37:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235141AbjHCJgS (ORCPT ); Thu, 3 Aug 2023 05:36:18 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0433135BF for ; Thu, 3 Aug 2023 02:34:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055276; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=k/nFqXA0wtAvy1b9IydNoKSYHTK903b7QUEoHi0uMCE=; b=fmxL9lSVqe6OPCN/fg1YMlDSyyuaGnue82XalcOuW/LHY3w68VzRjJVQBWs741xhJAMWtu kQB7rUJN4/bmhhyW9e9kDsWqxIFkoTR5oj9h9PIZ+xKEClrfwGsGVt2+0M5uS+hOk95Aic wF62WhYjajoZ4hJCnf2npiHK/YVDYtM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-515-owpUO1W9Pr2FVh3ovjWZrg-1; Thu, 03 Aug 2023 05:34:31 -0400 X-MC-Unique: owpUO1W9Pr2FVh3ovjWZrg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A2D66803FDC; Thu, 3 Aug 2023 09:34:30 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3C93E2166B25; Thu, 3 Aug 2023 09:34:29 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 24/32] media: ov2680: Fix exposure and gain ctrls range and default value Date: Thu, 3 Aug 2023 11:33:39 +0200 Message-ID: <20230803093348.15679-25-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The exposure control's max effective value is VTS - 8, set the control range to match this. Thas means that if/when a future commit makes VTS configurable as a control itself the exposure range needs to be updated dynamically to match the VTS value. The gain control goes from 0 - 1023, higher values wrap around to the lowest gain setting. The gain control, controls an analog gain so use V4L2_CID_ANALOGUE_GAIN for it instead of V4L2_CID_GAIN. Also stop setting 0 as default for both controls this leads to a totally black picture which is no good. This is esp. important for tests of the sensor driver without (userspace driven) auto exposure / gain. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- Changes in v4: - Use V4L2_CID_ANALOGUE_GAIN --- drivers/media/i2c/ov2680.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index ecd99e6669bd..b251265594b0 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -81,6 +81,9 @@ /* If possible send 16 extra rows / lines to the ISP as padding */ #define OV2680_END_MARGIN 16 +/* Max exposure time is VTS - 8 */ +#define OV2680_INTEGRATION_TIME_MARGIN 8 + #define OV2680_DEFAULT_WIDTH 800 #define OV2680_DEFAULT_HEIGHT 600 @@ -779,7 +782,7 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) } switch (ctrl->id) { - case V4L2_CID_GAIN: + case V4L2_CID_ANALOGUE_GAIN: ret = ov2680_gain_set(sensor, ctrl->val); break; case V4L2_CID_EXPOSURE: @@ -849,6 +852,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops; struct ov2680_ctrls *ctrls = &sensor->ctrls; struct v4l2_ctrl_handler *hdl = &ctrls->handler; + int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN; int ret = 0; v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_subdev_ops); @@ -874,9 +878,10 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) 0, 0, test_pattern_menu); ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, - 0, 32767, 1, 0); + 0, exp_max, 1, exp_max); - ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); + ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, + 0, 1023, 1, 250); if (hdl->error) { ret = hdl->error; From patchwork Thu Aug 3 09:33:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339614 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 EAAB3C00528 for ; Thu, 3 Aug 2023 09:37:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235050AbjHCJhR (ORCPT ); Thu, 3 Aug 2023 05:37:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33772 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234039AbjHCJgR (ORCPT ); Thu, 3 Aug 2023 05:36:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8836F35AA for ; Thu, 3 Aug 2023 02:34:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055275; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QuPf+Em/SwTiiKyE4NN115UM3dhfhnjbeHSpJYT53rU=; b=OwBeISlF0vrircA+XGD1Z9ZzzG1ec0izXP7/4GjddKigcaTxNM5Puq6Q76ZUvEIgBxgLMJ euDsKgov2kJxrdQTxb3V1vPWcEqfJyg6w/lz5x2q+WB22nMBWwQ8XJupQvWnkjnQqQRY3F VU5w0lftyM0soviXEohV+QJubOpZZmM= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-218-vqqZcdyPPeCOGD4dWGKN4g-1; Thu, 03 Aug 2023 05:34:32 -0400 X-MC-Unique: vqqZcdyPPeCOGD4dWGKN4g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4B3832808B21; Thu, 3 Aug 2023 09:34:32 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id D74DE2166B25; Thu, 3 Aug 2023 09:34:30 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 25/32] media: ov2680: Add a bunch of register tweaks Date: Thu, 3 Aug 2023 11:33:40 +0200 Message-ID: <20230803093348.15679-26-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Usually when developing a sensor driver with help from the vendor the vendor will provide a bunch of register tweaks for optimal performance of the sensor. The atomisp-ov2680.c driver was (presumably) developed by Intel with help from OmniVision and indeed contains a bunch of register tweaks. Add these register tweaks to the "main" ov2680.c driver. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index b251265594b0..e6c99c14da8f 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -180,18 +180,71 @@ static const int ov2680_hv_flip_bayer_order[] = { }; static const struct reg_sequence ov2680_global_setting[] = { + /* MIPI PHY, 0x10 -> 0x1c enable bp_c_hs_en_lat and bp_d_hs_en_lat */ + {0x3016, 0x1c}, + /* R MANUAL set exposure and gain to manual (hw does not do auto) */ {0x3503, 0x03}, + /* Analog control register tweaks */ + {0x3603, 0x39}, /* Reset value 0x99 */ + {0x3604, 0x24}, /* Reset value 0x74 */ + {0x3621, 0x37}, /* Reset value 0x44 */ + + /* Sensor control register tweaks */ + {0x3701, 0x64}, /* Reset value 0x61 */ + {0x3705, 0x3c}, /* Reset value 0x21 */ + {0x370c, 0x50}, /* Reset value 0x10 */ + {0x370d, 0xc0}, /* Reset value 0x00 */ + {0x3718, 0x88}, /* Reset value 0x80 */ + + /* PSRAM tweaks */ + {0x3781, 0x80}, /* Reset value 0x00 */ + {0x3784, 0x0c}, /* Reset value 0x00, based on OV2680_R1A_AM10.ovt */ + {0x3789, 0x60}, /* Reset value 0x50 */ + + /* BLC CTRL00 0x01 -> 0x81 set avg_weight to 8 */ + {0x4000, 0x81}, + /* Set black level compensation range to 0 - 3 (default 0 - 11) */ {0x4008, 0x00}, {0x4009, 0x03}, + /* VFIFO R2 0x00 -> 0x02 set Frame reset enable */ + {0x4602, 0x02}, + + /* MIPI ctrl CLK PREPARE MIN change from 0x26 (38) -> 0x36 (54) */ + {0x481f, 0x36}, + + /* MIPI ctrl CLK LPX P MIN change from 0x32 (50) -> 0x36 (54) */ + {0x4825, 0x36}, + + /* R ISP CTRL2 0x20 -> 0x30, set sof_sel bit */ + {0x5002, 0x30}, + /* * Window CONTROL 0x00 -> 0x01, enable manual window control, * this is necessary for full size flip and mirror support. */ {0x5708, 0x01}, + + /* + * DPC CTRL0 0x14 -> 0x3e, set enable_tail, enable_3x3_cluster + * and enable_general_tail bits based OV2680_R1A_AM10.ovt. + */ + {0x5780, 0x3e}, + + /* DPC MORE CONNECTION CASE THRE 0x0c (12) -> 0x02 (2) */ + {0x5788, 0x02}, + + /* DPC GAIN LIST1 0x0f (15) -> 0x08 (8) */ + {0x578e, 0x08}, + + /* DPC GAIN LIST2 0x3f (63) -> 0x0c (12) */ + {0x578f, 0x0c}, + + /* DPC THRE RATIO 0x04 (4) -> 0x00 (0) */ + {0x5792, 0x00}, }; static struct ov2680_dev *to_ov2680_dev(struct v4l2_subdev *sd) From patchwork Thu Aug 3 09:33:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339617 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 B3E5DC04A94 for ; Thu, 3 Aug 2023 09:37:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230335AbjHCJhX (ORCPT ); Thu, 3 Aug 2023 05:37:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235143AbjHCJgT (ORCPT ); Thu, 3 Aug 2023 05:36:19 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 38F483A81 for ; Thu, 3 Aug 2023 02:34:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055280; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yFx6BYu9bpB75AJ8M6xQoqsHjFu/31ufoi+KwnL/ToM=; b=UGWkxAJxxGwpiTLPm3Wxte2qsdJsFt/1ViWQW2KQg/nJ4VGA/xZD5OO4rnxgre6UXmvnaL /WSpg22jnZClkRxSQgsBsTfKb6z413U6mXDoW7/4AuOmfwcU+yKjaZcqKssFv6qdjCyFFC nVqAMJJ7qZg0vmlO99ZVMJ6EnL3G0rE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-44-3xI8MB2rNiOmVShyzHez0g-1; Thu, 03 Aug 2023 05:34:35 -0400 X-MC-Unique: 3xI8MB2rNiOmVShyzHez0g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E5A44856506; Thu, 3 Aug 2023 09:34:33 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7DDDD2166B25; Thu, 3 Aug 2023 09:34:32 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 26/32] media: ov2680: Drop unnecessary pad checks Date: Thu, 3 Aug 2023 11:33:41 +0200 Message-ID: <20230803093348.15679-27-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Drop unnecessary pad checks in enum_mbus_code, get_fmt, set_fmt this is already checked by check_pad() from drivers/media/v4l2-core/v4l2-subdev.c. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index e6c99c14da8f..c09a0e7f7787 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -591,7 +591,7 @@ static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, { struct ov2680_dev *sensor = to_ov2680_dev(sd); - if (code->pad != 0 || code->index != 0) + if (code->index != 0) return -EINVAL; code->code = sensor->mode.fmt.code; @@ -606,9 +606,6 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd, struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *fmt; - if (format->pad != 0) - return -EINVAL; - fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which); @@ -629,9 +626,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd, unsigned int width, height; int ret = 0; - if (format->pad != 0) - return -EINVAL; - crop = __ov2680_get_pad_crop(sensor, sd_state, format->pad, format->which); From patchwork Thu Aug 3 09:33:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339615 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 CC4D3C0015E for ; Thu, 3 Aug 2023 09:37:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235180AbjHCJhT (ORCPT ); Thu, 3 Aug 2023 05:37:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235142AbjHCJgS (ORCPT ); Thu, 3 Aug 2023 05:36:18 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02F523A80 for ; Thu, 3 Aug 2023 02:34:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055279; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9UcsjB5rRPcjxgnzDxzmeaRvxgVPxqS4oDq/b3K3X2k=; b=e39QAVj7R5k+QQ3enxh7Q+noQMYaC4q2jcXvfQD/0/0G3kiEjcSjdaCMdydB/9FDQlD3Zx m3MhcOKp3BPgjR4YcWD4dUQbTcXB83lWvPaNrfGM2M2MP+20T+nwtpF1MP5V5De4VBy+R8 caLfMewkDYcBa6GaxwzHuzHyp5rOwNk= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-530-uC17vZzQPPGpVI4ThMGEVA-1; Thu, 03 Aug 2023 05:34:36 -0400 X-MC-Unique: uC17vZzQPPGpVI4ThMGEVA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 8BE4F810BB2; Thu, 3 Aug 2023 09:34:35 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 254592166B25; Thu, 3 Aug 2023 09:34:34 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 27/32] media: ov2680: Read and log sensor revision during probe Date: Thu, 3 Aug 2023 11:33:42 +0200 Message-ID: <20230803093348.15679-28-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Read and log sensor revision during probe. Since this means that the driver will now already log a message on successful probe drop the "ov2680 init correctly" log message. Acked-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- drivers/media/i2c/ov2680.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index c09a0e7f7787..1f59013e440c 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -33,6 +33,7 @@ #define OV2680_REG_SOFT_RESET CCI_REG8(0x0103) #define OV2680_REG_CHIP_ID CCI_REG16(0x300a) +#define OV2680_REG_SC_CMMN_SUB_ID CCI_REG8(0x302a) #define OV2680_REG_PLL_MULTIPLIER CCI_REG16(0x3081) #define OV2680_REG_EXPOSURE_PK CCI_REG24(0x3500) @@ -966,13 +967,14 @@ static int ov2680_get_regulators(struct ov2680_dev *sensor) static int ov2680_check_id(struct ov2680_dev *sensor) { - u64 chip_id; - int ret; + u64 chip_id, rev; + int ret = 0; - ret = cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, NULL); + cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, &ret); + cci_read(sensor->regmap, OV2680_REG_SC_CMMN_SUB_ID, &rev, &ret); if (ret < 0) { dev_err(sensor->dev, "failed to read chip id\n"); - return -ENODEV; + return ret; } if (chip_id != OV2680_CHIP_ID) { @@ -981,6 +983,9 @@ static int ov2680_check_id(struct ov2680_dev *sensor) return -ENODEV; } + dev_info(sensor->dev, "sensor_revision id = 0x%llx, rev= %lld\n", + chip_id, rev & 0x0f); + return 0; } @@ -1121,8 +1126,6 @@ static int ov2680_probe(struct i2c_client *client) pm_runtime_use_autosuspend(&client->dev); pm_runtime_put_autosuspend(&client->dev); - dev_info(dev, "ov2680 init correctly\n"); - return 0; err_pm_runtime: From patchwork Thu Aug 3 09:33:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339621 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 DAF0DC00528 for ; Thu, 3 Aug 2023 09:37:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235094AbjHCJhc (ORCPT ); Thu, 3 Aug 2023 05:37:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234112AbjHCJg0 (ORCPT ); Thu, 3 Aug 2023 05:36:26 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 56DE43A9A for ; Thu, 3 Aug 2023 02:34:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hnAwueLUQXgVYtRRO1NBVgEiemeasyJQZpVC6Flu85w=; b=FtGKt/mHx5xm2VrjfN/z5oce3LNOThluY4QO7JihqAhocUBqUi1UK5g7+s0wA8tQIB1g8l +sdWgKfUB2tNOmYfZv9SEU23UCigTgrYe3kKQw8iKc9vbJrCOyGWKN7SzOEvF0GdyHEOiJ eXDDC+hneCzqBJwW12E4AZ2f6oc5tso= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-646--1JOHr2rMLi6TO83GePXIw-1; Thu, 03 Aug 2023 05:34:37 -0400 X-MC-Unique: -1JOHr2rMLi6TO83GePXIw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 2F74D810BB2; Thu, 3 Aug 2023 09:34:37 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id BE6142166B25; Thu, 3 Aug 2023 09:34:35 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 28/32] media: ov2680: Add link-freq and pixel-rate controls Date: Thu, 3 Aug 2023 11:33:43 +0200 Message-ID: <20230803093348.15679-29-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add read-only link-freq and pixel-rate controls. This is necessary for the sensor to work with the ipu3-cio2 driver and for libcamera. Acked-by: Rui Miguel Silva Signed-off-by: Hans de Goede --- Changes in v5: - Make pixel_rate u64 instead of s64 for do_div() to fix: drivers/media/i2c/ov2680.c:1092:2: warning: comparison of distinct pointer types ('typeof ((sensor->pixel_rate)) *' (aka 'long long *') and 'uint64_t *' (aka 'unsigned long long *')) [-Wcompare-distinct-pointer-types] Changes in v4: - Use do_div to calculate pixel_rate to avoid unresolved __divdi3 symbol --- drivers/media/i2c/ov2680.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 1f59013e440c..83ec034b5307 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -75,6 +75,12 @@ #define OV2680_MIN_CROP_WIDTH 2 #define OV2680_MIN_CROP_HEIGHT 2 +/* Fixed pre-div of 1/2 */ +#define OV2680_PLL_PREDIV0 2 + +/* Pre-div configurable through reg 0x3080, left at its default of 0x02 : 1/2 */ +#define OV2680_PLL_PREDIV 2 + /* 66MHz pixel clock: 66MHz / 1704 * 1294 = 30fps */ #define OV2680_PIXELS_PER_LINE 1704 #define OV2680_LINES_PER_FRAME 1294 @@ -121,6 +127,8 @@ struct ov2680_ctrls { struct v4l2_ctrl *hflip; struct v4l2_ctrl *vflip; struct v4l2_ctrl *test_pattern; + struct v4l2_ctrl *link_freq; + struct v4l2_ctrl *pixel_rate; }; struct ov2680_mode { @@ -147,6 +155,8 @@ struct ov2680_dev { struct clk *xvclk; u32 xvclk_freq; u8 pll_mult; + s64 link_freq[1]; + u64 pixel_rate; struct regulator_bulk_data supplies[OV2680_NUM_SUPPLIES]; struct gpio_desc *pwdn_gpio; @@ -931,6 +941,12 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 1023, 1, 250); + ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, NULL, V4L2_CID_LINK_FREQ, + 0, 0, sensor->link_freq); + ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, NULL, V4L2_CID_PIXEL_RATE, + 0, sensor->pixel_rate, + 1, sensor->pixel_rate); + if (hdl->error) { ret = hdl->error; goto cleanup_entity; @@ -938,6 +954,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor) ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; sensor->sd.ctrl_handler = hdl; @@ -1067,6 +1084,13 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) sensor->pll_mult = ov2680_pll_multipliers[i]; + sensor->link_freq[0] = sensor->xvclk_freq / OV2680_PLL_PREDIV0 / + OV2680_PLL_PREDIV * sensor->pll_mult; + + /* CSI-2 is double data rate, bus-format is 10 bpp */ + sensor->pixel_rate = sensor->link_freq[0] * 2; + do_div(sensor->pixel_rate, 10); + return 0; } From patchwork Thu Aug 3 09:33:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339618 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 2DA5DC00528 for ; Thu, 3 Aug 2023 09:37:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235235AbjHCJhZ (ORCPT ); Thu, 3 Aug 2023 05:37:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235145AbjHCJgT (ORCPT ); Thu, 3 Aug 2023 05:36:19 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61074213F for ; Thu, 3 Aug 2023 02:34:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055283; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UeJfKrSWTX8+/jDmovl06WfeG5HYQ4aXeIF1EDNjzoQ=; b=JJH2N0ITOHIDQ7heuXB2iHoM6RAkk5Sr6tMB1oRnoYOMcHxLuceIVkt7FgsTaLz8habZp7 rdOCkg3DmzcLnL9yXmeg4iyDPFCE3VCktQMrmnkqhyWp20+MraFjlFoQ0o64TcHsqy9ZY6 ZLju/zgo8hYlVR73DgM1RNFF+CFL/A8= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-478-zyx67YwBPbulzoV0Yi_KJw-1; Thu, 03 Aug 2023 05:34:39 -0400 X-MC-Unique: zyx67YwBPbulzoV0Yi_KJw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C64D93C01BAD; Thu, 3 Aug 2023 09:34:38 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 622AC2166B25; Thu, 3 Aug 2023 09:34:37 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 29/32] media: ov2680: Add bus-cfg / endpoint property verification Date: Thu, 3 Aug 2023 11:33:44 +0200 Message-ID: <20230803093348.15679-30-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Verify that the number of CSI lanes and link-frequency specified in the endpoint fwnode are correct. Signed-off-by: Hans de Goede --- Changes in v4: - New patch in v4 of this patch-set --- drivers/media/i2c/ov2680.c | 60 +++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c index 83ec034b5307..72bab0ff8a36 100644 --- a/drivers/media/i2c/ov2680.c +++ b/drivers/media/i2c/ov2680.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define OV2680_CHIP_ID 0x2680 @@ -1008,6 +1009,9 @@ static int ov2680_check_id(struct ov2680_dev *sensor) static int ov2680_parse_dt(struct ov2680_dev *sensor) { + struct v4l2_fwnode_endpoint bus_cfg = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; struct device *dev = sensor->dev; struct fwnode_handle *ep_fwnode; struct gpio_desc *gpio; @@ -1023,7 +1027,10 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) return dev_err_probe(dev, -EPROBE_DEFER, "waiting for fwnode graph endpoint\n"); + ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &bus_cfg); fwnode_handle_put(ep_fwnode); + if (ret) + return ret; /* * The pin we want is named XSHUTDN in the datasheet. Linux sensor @@ -1038,15 +1045,16 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) ret = PTR_ERR_OR_ZERO(gpio); if (ret < 0) { dev_dbg(dev, "error while getting reset gpio: %d\n", ret); - return ret; + goto out_free_bus_cfg; } sensor->pwdn_gpio = gpio; sensor->xvclk = devm_clk_get_optional(dev, "xvclk"); if (IS_ERR(sensor->xvclk)) { - dev_err(dev, "xvclk clock missing or invalid\n"); - return PTR_ERR(sensor->xvclk); + ret = dev_err_probe(dev, PTR_ERR(sensor->xvclk), + "xvclk clock missing or invalid\n"); + goto out_free_bus_cfg; } /* @@ -1060,14 +1068,17 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) */ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", &rate); - if (ret && !sensor->xvclk) - return dev_err_probe(dev, ret, "invalid clock config\n"); + if (ret && !sensor->xvclk) { + dev_err_probe(dev, ret, "invalid clock config\n"); + goto out_free_bus_cfg; + } if (!ret && sensor->xvclk) { ret = clk_set_rate(sensor->xvclk, rate); - if (ret) - return dev_err_probe(dev, ret, - "failed to set clock rate\n"); + if (ret) { + dev_err_probe(dev, ret, "failed to set clock rate\n"); + goto out_free_bus_cfg; + } } sensor->xvclk_freq = rate ?: clk_get_rate(sensor->xvclk); @@ -1077,10 +1088,12 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) break; } - if (i == ARRAY_SIZE(ov2680_xvclk_freqs)) - return dev_err_probe(dev, -EINVAL, - "unsupported xvclk frequency %d Hz\n", - sensor->xvclk_freq); + if (i == ARRAY_SIZE(ov2680_xvclk_freqs)) { + ret = dev_err_probe(dev, -EINVAL, + "unsupported xvclk frequency %d Hz\n", + sensor->xvclk_freq); + goto out_free_bus_cfg; + } sensor->pll_mult = ov2680_pll_multipliers[i]; @@ -1091,7 +1104,28 @@ static int ov2680_parse_dt(struct ov2680_dev *sensor) sensor->pixel_rate = sensor->link_freq[0] * 2; do_div(sensor->pixel_rate, 10); - return 0; + /* Verify bus cfg */ + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1) { + ret = dev_err_probe(dev, -EINVAL, + "only a 1-lane CSI2 config is supported"); + goto out_free_bus_cfg; + } + + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) + if (bus_cfg.link_frequencies[i] == sensor->link_freq[0]) + break; + + if (bus_cfg.nr_of_link_frequencies == 0 || + bus_cfg.nr_of_link_frequencies == i) { + ret = dev_err_probe(dev, -EINVAL, + "supported link freq %lld not found\n", + sensor->link_freq[0]); + goto out_free_bus_cfg; + } + +out_free_bus_cfg: + v4l2_fwnode_endpoint_free(&bus_cfg); + return ret; } static int ov2680_probe(struct i2c_client *client) From patchwork Thu Aug 3 09:33:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339622 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 D5BEDC0015E for ; Thu, 3 Aug 2023 09:37:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235096AbjHCJhd (ORCPT ); Thu, 3 Aug 2023 05:37:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235123AbjHCJg0 (ORCPT ); Thu, 3 Aug 2023 05:36:26 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3ADF30FF for ; Thu, 3 Aug 2023 02:34:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055284; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kmFxdIVPuLqC1j0PdkbqpqLArIEzt/Tnmml1oyk6O/E=; b=BbwZmPo7thE769ddsRriDiH1s74SWIlgOPM4HVGA23BA3G+/pTeEheWAlwi7bKaYIkQiQk HbCyx+vyUwUt3SVKId6csEebyyTfRvM9rhTXu0MbBbyKCJZrlrFWL37s2LsnQbToqGdKxG DVq8ZZeYGTEgdEYFEozLqqREGPhLAuM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-690-IPYkAYXNNHu6RfjfgZKa9g-1; Thu, 03 Aug 2023 05:34:40 -0400 X-MC-Unique: IPYkAYXNNHu6RfjfgZKa9g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6B48F8564EF; Thu, 3 Aug 2023 09:34:40 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04C962166B25; Thu, 3 Aug 2023 09:34:38 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 30/32] MAINTAINERS: Add Hans de Goede as OV2680 sensor driver maintainer Date: Thu, 3 Aug 2023 11:33:45 +0200 Message-ID: <20230803093348.15679-31-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add myself as OV2680 sensor driver maintainer. Reviewed-by: Rui Miguel Silva Reviewed-by: Daniel Scally Signed-off-by: Hans de Goede --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0600c2f29080..9369a35c23a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15608,6 +15608,7 @@ F: drivers/media/i2c/ov13b10.c OMNIVISION OV2680 SENSOR DRIVER M: Rui Miguel Silva +M: Hans de Goede L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git From patchwork Thu Aug 3 09:33:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339619 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 DDC31C04A6A for ; Thu, 3 Aug 2023 09:37:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235064AbjHCJh0 (ORCPT ); Thu, 3 Aug 2023 05:37:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235164AbjHCJgY (ORCPT ); Thu, 3 Aug 2023 05:36:24 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA0DF3A8D for ; Thu, 3 Aug 2023 02:34:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055288; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zv4wc/KrPFjSdLd8ZjfVcuoMD+rO4L1aVjHfc9rhDPg=; b=BecPywm/JSXdu3t0D0Tej4AJ1Isjb0Q1Tz30URDMZdNO4aA1hRbU/A49WIxeiUG9aK7/a2 bS6t0dqBE9hKzFnQ+B8SdQSnOCo+3CUZObKJO248l0GaKyC6T+h8Kl6UCGg4JZbCNtXYJR bxG9bzaDR9/Mfu1UMa4+yO31cy5JOIY= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-602-NzHTa2DWPCKK_dgMxHFg_Q-1; Thu, 03 Aug 2023 05:34:42 -0400 X-MC-Unique: NzHTa2DWPCKK_dgMxHFg_Q-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0F291104458A; Thu, 3 Aug 2023 09:34:42 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9DF4C2166B25; Thu, 3 Aug 2023 09:34:40 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org Subject: [PATCH v5 31/32] media: ipu-bridge: Add link-frequency to OV2680 ipu_supported_sensors[] entry Date: Thu, 3 Aug 2023 11:33:46 +0200 Message-ID: <20230803093348.15679-32-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Now that the ov2680 driver verifies the bus-cfg from the endpoint fwnode the link-frequency must be set for things to work. Signed-off-by: Hans de Goede --- drivers/media/pci/intel/ipu-bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c index 940457940057..be9ab2ab6b8d 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -30,7 +30,7 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { /* Omnivision OV7251 */ IPU_SENSOR_CONFIG("INT347E", 1, 319200000), /* Omnivision OV2680 */ - IPU_SENSOR_CONFIG("OVTI2680", 0), + IPU_SENSOR_CONFIG("OVTI2680", 1, 331200000), /* Omnivision ov8856 */ IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000), /* Omnivision ov2740 */ From patchwork Thu Aug 3 09:33:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13339620 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 3F45DC04A6A for ; Thu, 3 Aug 2023 09:37:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235160AbjHCJh3 (ORCPT ); Thu, 3 Aug 2023 05:37:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235154AbjHCJgZ (ORCPT ); Thu, 3 Aug 2023 05:36:25 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9306C30F9 for ; Thu, 3 Aug 2023 02:34:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691055289; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F93W0SzacRsHfFSLj5FPz0pSJmAK+0CS06fYAkGWhAs=; b=V623jPRjpIUclJ6/OMqp+YoOdqtY8JuVUSmNVJmOdwKruKGP50GAniyDSOZWOFPWOiDXQG L8f2sLptUeXwn1AnSl1eWLUbBA/q024KMrrM6X0DQdhgQ5HJ5GpVc1QaKkLyMWtS5LNB+3 3HU1oaJnT4eS5/3yOXF/41pza1K27CE= Received: from mimecast-mx02.redhat.com (66.187.233.73 [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-204-t1v1CbYjOLGrlaQlZVKTGA-1; Thu, 03 Aug 2023 05:34:44 -0400 X-MC-Unique: t1v1CbYjOLGrlaQlZVKTGA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id DED851C04B63; Thu, 3 Aug 2023 09:34:43 +0000 (UTC) Received: from shalem.redhat.com (unknown [10.39.193.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 41E072166B25; Thu, 3 Aug 2023 09:34:42 +0000 (UTC) From: Hans de Goede To: Sakari Ailus , Laurent Pinchart , Rui Miguel Silva , Daniel Scally Cc: Hans de Goede , Mauro Carvalho Chehab , Andy Shevchenko , Kate Hsuan , Dave Stevenson , Tommaso Merciai , linux-media@vger.kernel.org, Andy Shevchenko Subject: [PATCH v5 32/32] media: atomisp: Drop atomisp-ov2680 sensor driver Date: Thu, 3 Aug 2023 11:33:47 +0200 Message-ID: <20230803093348.15679-33-hdegoede@redhat.com> In-Reply-To: <20230803093348.15679-1-hdegoede@redhat.com> References: <20230803093348.15679-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org After recent improvements to atomisp and the standard ov2680 sensor driver, the atomisp driver now works fine with the standard ov2680 driver. Drop the no longer necessary atomisp specific atomisp-ov2680 sensor driver. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede --- drivers/staging/media/atomisp/i2c/Kconfig | 13 - drivers/staging/media/atomisp/i2c/Makefile | 1 - .../media/atomisp/i2c/atomisp-ov2680.c | 828 ------------------ drivers/staging/media/atomisp/i2c/ov2680.h | 173 ---- 4 files changed, 1015 deletions(-) delete mode 100644 drivers/staging/media/atomisp/i2c/atomisp-ov2680.c delete mode 100644 drivers/staging/media/atomisp/i2c/ov2680.h diff --git a/drivers/staging/media/atomisp/i2c/Kconfig b/drivers/staging/media/atomisp/i2c/Kconfig index e34646d7dadc..2d4165cda2f1 100644 --- a/drivers/staging/media/atomisp/i2c/Kconfig +++ b/drivers/staging/media/atomisp/i2c/Kconfig @@ -57,19 +57,6 @@ config VIDEO_ATOMISP_GC0310 This is a Video4Linux2 sensor-level driver for the Galaxycore GC0310 0.3MP sensor. -config VIDEO_ATOMISP_OV2680 - tristate "Omnivision OV2680 sensor support" - depends on ACPI - depends on I2C && VIDEO_DEV - select V4L2_CCI_I2C - help - This is a Video4Linux2 sensor-level driver for the Omnivision - OV2680 raw camera. - - ov2680 is a 2M raw sensor. - - It currently only works with the atomisp driver. - config VIDEO_ATOMISP_OV5693 tristate "Omnivision ov5693 sensor support" depends on ACPI diff --git a/drivers/staging/media/atomisp/i2c/Makefile b/drivers/staging/media/atomisp/i2c/Makefile index 8d022986e199..fc55af5f3422 100644 --- a/drivers/staging/media/atomisp/i2c/Makefile +++ b/drivers/staging/media/atomisp/i2c/Makefile @@ -7,7 +7,6 @@ obj-$(CONFIG_VIDEO_ATOMISP_OV5693) += ov5693/ obj-$(CONFIG_VIDEO_ATOMISP_MT9M114) += atomisp-mt9m114.o obj-$(CONFIG_VIDEO_ATOMISP_GC2235) += atomisp-gc2235.o obj-$(CONFIG_VIDEO_ATOMISP_OV2722) += atomisp-ov2722.o -obj-$(CONFIG_VIDEO_ATOMISP_OV2680) += atomisp-ov2680.o obj-$(CONFIG_VIDEO_ATOMISP_GC0310) += atomisp-gc0310.o obj-$(CONFIG_VIDEO_ATOMISP_MSRLIST_HELPER) += atomisp-libmsrlisthelper.o diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c deleted file mode 100644 index f933a65ac8d4..000000000000 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c +++ /dev/null @@ -1,828 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Support for OmniVision OV2680 1080p HD camera sensor. - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * Copyright (c) 2023 Hans de Goede - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ov2680.h" - -#define OV2680_CHIP_ID 0x2680 - -#define OV2680_REG_STREAM_CTRL CCI_REG8(0x0100) -#define OV2680_REG_SOFT_RESET CCI_REG8(0x0103) - -#define OV2680_REG_CHIP_ID CCI_REG16(0x300a) -#define OV2680_REG_SC_CMMN_SUB_ID CCI_REG8(0x302a) - -#define OV2680_REG_EXPOSURE_PK CCI_REG24(0x3500) -#define OV2680_REG_R_MANUAL CCI_REG8(0x3503) -#define OV2680_REG_GAIN_PK CCI_REG16(0x350a) - -#define OV2680_REG_SENSOR_CTRL_0A CCI_REG8(0x370a) - -#define OV2680_REG_HORIZONTAL_START CCI_REG16(0x3800) -#define OV2680_REG_VERTICAL_START CCI_REG16(0x3802) -#define OV2680_REG_HORIZONTAL_END CCI_REG16(0x3804) -#define OV2680_REG_VERTICAL_END CCI_REG16(0x3806) -#define OV2680_REG_HORIZONTAL_OUTPUT_SIZE CCI_REG16(0x3808) -#define OV2680_REG_VERTICAL_OUTPUT_SIZE CCI_REG16(0x380a) -#define OV2680_REG_TIMING_HTS CCI_REG16(0x380c) -#define OV2680_REG_TIMING_VTS CCI_REG16(0x380e) -#define OV2680_REG_ISP_X_WIN CCI_REG16(0x3810) -#define OV2680_REG_ISP_Y_WIN CCI_REG16(0x3812) -#define OV2680_REG_X_INC CCI_REG8(0x3814) -#define OV2680_REG_Y_INC CCI_REG8(0x3815) -#define OV2680_REG_FORMAT1 CCI_REG8(0x3820) -#define OV2680_REG_FORMAT2 CCI_REG8(0x3821) - -#define OV2680_REG_ISP_CTRL00 CCI_REG8(0x5080) - -#define OV2680_REG_X_WIN CCI_REG16(0x5704) -#define OV2680_REG_Y_WIN CCI_REG16(0x5706) - -#define OV2680_FRAME_RATE 30 -#define OV2680_INTEGRATION_TIME_MARGIN 8 - -static const struct v4l2_rect ov2680_default_crop = { - .left = OV2680_ACTIVE_START_LEFT, - .top = OV2680_ACTIVE_START_TOP, - .width = OV2680_ACTIVE_WIDTH, - .height = OV2680_ACTIVE_HEIGHT, -}; - -static void ov2680_set_bayer_order(struct ov2680_dev *sensor, struct v4l2_mbus_framefmt *fmt) -{ - static const int ov2680_hv_flip_bayer_order[] = { - MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SGRBG10_1X10, - MEDIA_BUS_FMT_SGBRG10_1X10, - MEDIA_BUS_FMT_SRGGB10_1X10, - }; - int hv_flip = 0; - - if (sensor->ctrls.vflip->val) - hv_flip += 1; - - if (sensor->ctrls.hflip->val) - hv_flip += 2; - - fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; -} - -static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) -{ - int ret; - - if (sensor->is_streaming) - return -EBUSY; - - ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT1, BIT(2), - val ? BIT(2) : 0, NULL); - if (ret < 0) - return ret; - - ov2680_set_bayer_order(sensor, &sensor->mode.fmt); - return 0; -} - -static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) -{ - int ret; - - if (sensor->is_streaming) - return -EBUSY; - - ret = cci_update_bits(sensor->regmap, OV2680_REG_FORMAT2, BIT(2), - val ? BIT(2) : 0, NULL); - if (ret < 0) - return ret; - - ov2680_set_bayer_order(sensor, &sensor->mode.fmt); - return 0; -} - -static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) -{ - return cci_write(sensor->regmap, OV2680_REG_EXPOSURE_PK, exp << 4, - NULL); -} - -static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) -{ - return cci_write(sensor->regmap, OV2680_REG_GAIN_PK, gain, NULL); -} - -static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) -{ - int ret = 0; - - if (!value) - return cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, - BIT(7), 0, NULL); - - cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, 0x03, value - 1, - &ret); - cci_update_bits(sensor->regmap, OV2680_REG_ISP_CTRL00, BIT(7), BIT(7), - &ret); - - return ret; -} - -static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - int ret; - - /* Only apply changes to the controls if the device is powered up */ - if (!pm_runtime_get_if_in_use(sensor->sd.dev)) { - ov2680_set_bayer_order(sensor, &sensor->mode.fmt); - return 0; - } - - switch (ctrl->id) { - case V4L2_CID_VFLIP: - ret = ov2680_set_vflip(sensor, ctrl->val); - break; - case V4L2_CID_HFLIP: - ret = ov2680_set_hflip(sensor, ctrl->val); - break; - case V4L2_CID_EXPOSURE: - ret = ov2680_exposure_set(sensor, ctrl->val); - break; - case V4L2_CID_GAIN: - ret = ov2680_gain_set(sensor, ctrl->val); - break; - case V4L2_CID_TEST_PATTERN: - ret = ov2680_test_pattern_set(sensor, ctrl->val); - break; - default: - ret = -EINVAL; - } - - pm_runtime_put(sensor->sd.dev); - return ret; -} - -static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { - .s_ctrl = ov2680_s_ctrl, -}; - -static int ov2680_init_registers(struct v4l2_subdev *sd) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - int ret; - - ret = cci_write(sensor->regmap, OV2680_REG_SOFT_RESET, 0x01, NULL); - if (ret < 0) - return ret; - - /* Wait for sensor reset */ - usleep_range(1000, 2000); - - return regmap_multi_reg_write(sensor->regmap, ov2680_global_setting, - ARRAY_SIZE(ov2680_global_setting)); -} - -static struct v4l2_mbus_framefmt * -__ov2680_get_pad_format(struct ov2680_dev *sensor, struct v4l2_subdev_state *state, - unsigned int pad, enum v4l2_subdev_format_whence which) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&sensor->sd, state, pad); - - return &sensor->mode.fmt; -} - -static struct v4l2_rect * -__ov2680_get_pad_crop(struct ov2680_dev *sensor, struct v4l2_subdev_state *state, - unsigned int pad, enum v4l2_subdev_format_whence which) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_crop(&sensor->sd, state, pad); - - return &sensor->mode.crop; -} - -static void ov2680_fill_format(struct ov2680_dev *sensor, - struct v4l2_mbus_framefmt *fmt, - unsigned int width, unsigned int height) -{ - memset(fmt, 0, sizeof(*fmt)); - fmt->width = width; - fmt->height = height; - fmt->field = V4L2_FIELD_NONE; - ov2680_set_bayer_order(sensor, fmt); -} - -static void ov2680_calc_mode(struct ov2680_dev *sensor) -{ - int width = sensor->mode.fmt.width; - int height = sensor->mode.fmt.height; - int orig_width = width; - int orig_height = height; - - if (width <= (sensor->mode.crop.width / 2) && - height <= (sensor->mode.crop.height / 2)) { - sensor->mode.binning = true; - width *= 2; - height *= 2; - } else { - sensor->mode.binning = false; - } - - sensor->mode.h_start = - (sensor->mode.crop.left + (sensor->mode.crop.width - width) / 2) & ~1; - sensor->mode.v_start = - (sensor->mode.crop.top + (sensor->mode.crop.height - height) / 2) & ~1; - sensor->mode.h_end = min(sensor->mode.h_start + width + OV2680_END_MARGIN - 1, - OV2680_NATIVE_WIDTH - 1); - sensor->mode.v_end = min(sensor->mode.v_start + height + OV2680_END_MARGIN - 1, - OV2680_NATIVE_HEIGHT - 1); - sensor->mode.h_output_size = orig_width; - sensor->mode.v_output_size = orig_height; - sensor->mode.hts = OV2680_PIXELS_PER_LINE; - sensor->mode.vts = OV2680_LINES_PER_FRAME; -} - -static int ov2680_set_mode(struct ov2680_dev *sensor) -{ - u8 sensor_ctrl_0a, inc, fmt1, fmt2; - int ret = 0; - - if (sensor->mode.binning) { - sensor_ctrl_0a = 0x23; - inc = 0x31; - fmt1 = 0xc2; - fmt2 = 0x01; - } else { - sensor_ctrl_0a = 0x21; - inc = 0x11; - fmt1 = 0xc0; - fmt2 = 0x00; - } - - cci_write(sensor->regmap, OV2680_REG_SENSOR_CTRL_0A, - sensor_ctrl_0a, &ret); - cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_START, - sensor->mode.h_start, &ret); - cci_write(sensor->regmap, OV2680_REG_VERTICAL_START, - sensor->mode.v_start, &ret); - cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_END, - sensor->mode.h_end, &ret); - cci_write(sensor->regmap, OV2680_REG_VERTICAL_END, - sensor->mode.v_end, &ret); - cci_write(sensor->regmap, OV2680_REG_HORIZONTAL_OUTPUT_SIZE, - sensor->mode.h_output_size, &ret); - cci_write(sensor->regmap, OV2680_REG_VERTICAL_OUTPUT_SIZE, - sensor->mode.v_output_size, &ret); - cci_write(sensor->regmap, OV2680_REG_TIMING_HTS, - sensor->mode.hts, &ret); - cci_write(sensor->regmap, OV2680_REG_TIMING_VTS, - sensor->mode.vts, &ret); - cci_write(sensor->regmap, OV2680_REG_ISP_X_WIN, 0, &ret); - cci_write(sensor->regmap, OV2680_REG_ISP_Y_WIN, 0, &ret); - cci_write(sensor->regmap, OV2680_REG_X_INC, inc, &ret); - cci_write(sensor->regmap, OV2680_REG_Y_INC, inc, &ret); - cci_write(sensor->regmap, OV2680_REG_X_WIN, - sensor->mode.h_output_size, &ret); - cci_write(sensor->regmap, OV2680_REG_Y_WIN, - sensor->mode.v_output_size, &ret); - cci_write(sensor->regmap, OV2680_REG_FORMAT1, fmt1, &ret); - cci_write(sensor->regmap, OV2680_REG_FORMAT2, fmt2, &ret); - - return ret; -} - -static int ov2680_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - struct v4l2_mbus_framefmt *fmt; - const struct v4l2_rect *crop; - unsigned int width, height; - - crop = __ov2680_get_pad_crop(sensor, sd_state, format->pad, format->which); - - /* Limit set_fmt max size to crop width / height */ - width = clamp_t(unsigned int, ALIGN(format->format.width, 2), - OV2680_MIN_CROP_WIDTH, crop->width); - height = clamp_t(unsigned int, ALIGN(format->format.height, 2), - OV2680_MIN_CROP_HEIGHT, crop->height); - - fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which); - ov2680_fill_format(sensor, fmt, width, height); - - format->format = *fmt; - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) - return 0; - - mutex_lock(&sensor->lock); - ov2680_calc_mode(sensor); - mutex_unlock(&sensor->lock); - return 0; -} - -static int ov2680_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - struct v4l2_mbus_framefmt *fmt; - - fmt = __ov2680_get_pad_format(sensor, sd_state, format->pad, format->which); - format->format = *fmt; - return 0; -} - -static int ov2680_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - struct v4l2_subdev_selection *sel) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - - switch (sel->target) { - case V4L2_SEL_TGT_CROP: - mutex_lock(&sensor->lock); - sel->r = *__ov2680_get_pad_crop(sensor, state, sel->pad, sel->which); - mutex_unlock(&sensor->lock); - break; - case V4L2_SEL_TGT_NATIVE_SIZE: - case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.top = 0; - sel->r.left = 0; - sel->r.width = OV2680_NATIVE_WIDTH; - sel->r.height = OV2680_NATIVE_HEIGHT; - break; - case V4L2_SEL_TGT_CROP_DEFAULT: - sel->r.top = OV2680_ACTIVE_START_TOP; - sel->r.left = OV2680_ACTIVE_START_LEFT; - sel->r.width = OV2680_ACTIVE_WIDTH; - sel->r.height = OV2680_ACTIVE_HEIGHT; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ov2680_set_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - struct v4l2_subdev_selection *sel) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - struct v4l2_mbus_framefmt *format; - struct v4l2_rect *__crop; - struct v4l2_rect rect; - - if (sel->target != V4L2_SEL_TGT_CROP) - return -EINVAL; - - /* - * Clamp the boundaries of the crop rectangle to the size of the sensor - * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't - * disrupted. - */ - rect.left = clamp(ALIGN(sel->r.left, 2), OV2680_NATIVE_START_LEFT, - OV2680_NATIVE_WIDTH); - rect.top = clamp(ALIGN(sel->r.top, 2), OV2680_NATIVE_START_TOP, - OV2680_NATIVE_HEIGHT); - rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), - OV2680_MIN_CROP_WIDTH, OV2680_NATIVE_WIDTH); - rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), - OV2680_MIN_CROP_HEIGHT, OV2680_NATIVE_HEIGHT); - - /* Make sure the crop rectangle isn't outside the bounds of the array */ - rect.width = min_t(unsigned int, rect.width, - OV2680_NATIVE_WIDTH - rect.left); - rect.height = min_t(unsigned int, rect.height, - OV2680_NATIVE_HEIGHT - rect.top); - - __crop = __ov2680_get_pad_crop(sensor, state, sel->pad, sel->which); - - if (rect.width != __crop->width || rect.height != __crop->height) { - /* - * Reset the output image size if the crop rectangle size has - * been modified. - */ - format = __ov2680_get_pad_format(sensor, state, sel->pad, sel->which); - format->width = rect.width; - format->height = rect.height; - } - - *__crop = rect; - sel->r = rect; - - return 0; -} - -static int ov2680_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state) -{ - struct v4l2_subdev_format fmt = { - .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, - .format = { - .width = 800, - .height = 600, - }, - }; - - sd_state->pads[0].try_crop = ov2680_default_crop; - - return ov2680_set_fmt(sd, sd_state, &fmt); -} - -static int ov2680_detect(struct ov2680_dev *sensor) -{ - u64 chip_id, rev; - int ret = 0; - - cci_read(sensor->regmap, OV2680_REG_CHIP_ID, &chip_id, &ret); - cci_read(sensor->regmap, OV2680_REG_SC_CMMN_SUB_ID, &rev, &ret); - if (ret < 0) { - dev_err(sensor->dev, "failed to read chip id\n"); - return -ENODEV; - } - - if (chip_id != OV2680_CHIP_ID) { - dev_err(sensor->dev, "chip id: 0x%04llx does not match expected 0x%04x\n", - chip_id, OV2680_CHIP_ID); - return -ENODEV; - } - - dev_info(sensor->dev, "sensor_revision id = 0x%llx, rev= %lld\n", - chip_id, rev & 0x0f); - - return 0; -} - -static int ov2680_s_stream(struct v4l2_subdev *sd, int enable) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret = 0; - - mutex_lock(&sensor->lock); - - if (sensor->is_streaming == enable) { - dev_warn(&client->dev, "stream already %s\n", enable ? "started" : "stopped"); - goto error_unlock; - } - - if (enable) { - ret = pm_runtime_get_sync(sensor->sd.dev); - if (ret < 0) - goto error_power_down; - - ret = ov2680_set_mode(sensor); - if (ret) - goto error_power_down; - - /* Restore value of all ctrls */ - ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret) - goto error_power_down; - - ret = cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 1, - NULL); - if (ret) - goto error_power_down; - } else { - cci_write(sensor->regmap, OV2680_REG_STREAM_CTRL, 0, NULL); - pm_runtime_put(sensor->sd.dev); - } - - sensor->is_streaming = enable; - v4l2_ctrl_activate(sensor->ctrls.vflip, !enable); - v4l2_ctrl_activate(sensor->ctrls.hflip, !enable); - - mutex_unlock(&sensor->lock); - return 0; - -error_power_down: - pm_runtime_put(sensor->sd.dev); - sensor->is_streaming = false; -error_unlock: - mutex_unlock(&sensor->lock); - return ret; -} - -static int ov2680_s_config(struct v4l2_subdev *sd) -{ - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - int ret; - - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - dev_err(&client->dev, "ov2680 power-up err.\n"); - goto fail_power_on; - } - - /* config & detect sensor */ - ret = ov2680_detect(sensor); - if (ret) - dev_err(&client->dev, "ov2680_detect err s_config.\n"); - -fail_power_on: - pm_runtime_put(&client->dev); - return ret; -} - -static int ov2680_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *interval) -{ - interval->interval.numerator = 1; - interval->interval.denominator = OV2680_FRAME_RATE; - return 0; -} - -static int ov2680_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) -{ - /* We support only a single format */ - if (code->index) - return -EINVAL; - - code->code = MEDIA_BUS_FMT_SBGGR10_1X10; - return 0; -} - -static int ov2680_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) -{ - static const struct v4l2_frmsize_discrete ov2680_frame_sizes[] = { - { 1616, 1216 }, - { 1616, 1096 }, - { 1616, 916 }, - { 1456, 1096 }, - { 1296, 976 }, - { 1296, 736 }, - { 784, 592 }, - { 656, 496 }, - }; - int index = fse->index; - - if (index >= ARRAY_SIZE(ov2680_frame_sizes)) - return -EINVAL; - - fse->min_width = ov2680_frame_sizes[index].width; - fse->min_height = ov2680_frame_sizes[index].height; - fse->max_width = ov2680_frame_sizes[index].width; - fse->max_height = ov2680_frame_sizes[index].height; - - return 0; -} - -static int ov2680_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval_enum *fie) -{ - /* Only 1 framerate */ - if (fie->index) - return -EINVAL; - - fie->interval.numerator = 1; - fie->interval.denominator = OV2680_FRAME_RATE; - return 0; -} - -static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames) -{ - *frames = OV2680_SKIP_FRAMES; - return 0; -} - -static const struct v4l2_subdev_video_ops ov2680_video_ops = { - .s_stream = ov2680_s_stream, - .g_frame_interval = ov2680_g_frame_interval, -}; - -static const struct v4l2_subdev_sensor_ops ov2680_sensor_ops = { - .g_skip_frames = ov2680_g_skip_frames, -}; - -static const struct v4l2_subdev_pad_ops ov2680_pad_ops = { - .init_cfg = ov2680_init_cfg, - .enum_mbus_code = ov2680_enum_mbus_code, - .enum_frame_size = ov2680_enum_frame_size, - .enum_frame_interval = ov2680_enum_frame_interval, - .get_fmt = ov2680_get_fmt, - .set_fmt = ov2680_set_fmt, - .get_selection = ov2680_get_selection, - .set_selection = ov2680_set_selection, -}; - -static const struct v4l2_subdev_ops ov2680_ops = { - .video = &ov2680_video_ops, - .pad = &ov2680_pad_ops, - .sensor = &ov2680_sensor_ops, -}; - -static int ov2680_init_controls(struct ov2680_dev *sensor) -{ - static const char * const test_pattern_menu[] = { - "Disabled", - "Color Bars", - "Random Data", - "Square", - "Black Image", - }; - const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops; - struct ov2680_ctrls *ctrls = &sensor->ctrls; - struct v4l2_ctrl_handler *hdl = &ctrls->handler; - int exp_max = OV2680_LINES_PER_FRAME - OV2680_INTEGRATION_TIME_MARGIN; - - v4l2_ctrl_handler_init(hdl, 4); - - hdl->lock = &sensor->lock; - - ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0); - ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, - 0, exp_max, 1, exp_max); - ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250); - ctrls->test_pattern = - v4l2_ctrl_new_std_menu_items(hdl, - &ov2680_ctrl_ops, V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(test_pattern_menu) - 1, - 0, 0, test_pattern_menu); - - ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - - if (hdl->error) - return hdl->error; - - sensor->sd.ctrl_handler = hdl; - return 0; -} - -static void ov2680_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - - dev_dbg(&client->dev, "ov2680_remove...\n"); - - v4l2_async_unregister_subdev(&sensor->sd); - media_entity_cleanup(&sensor->sd.entity); - v4l2_ctrl_handler_free(&sensor->ctrls.handler); - mutex_destroy(&sensor->lock); - fwnode_handle_put(sensor->ep_fwnode); - pm_runtime_disable(&client->dev); -} - -static int ov2680_probe(struct i2c_client *client) -{ - struct device *dev = &client->dev; - struct ov2680_dev *sensor; - int ret; - - sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); - if (!sensor) - return -ENOMEM; - - sensor->regmap = devm_cci_regmap_init_i2c(client, 16); - if (IS_ERR(sensor->regmap)) - return PTR_ERR(sensor->regmap); - - mutex_init(&sensor->lock); - - sensor->dev = &client->dev; - v4l2_i2c_subdev_init(&sensor->sd, client, &ov2680_ops); - - /* - * Sometimes the fwnode graph is initialized by the bridge driver. - * Bridge drivers doing this may also add GPIO mappings, wait for this. - */ - sensor->ep_fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); - if (!sensor->ep_fwnode) - return dev_err_probe(dev, -EPROBE_DEFER, "waiting for fwnode graph endpoint\n"); - - sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH); - if (IS_ERR(sensor->powerdown)) { - fwnode_handle_put(sensor->ep_fwnode); - return dev_err_probe(dev, PTR_ERR(sensor->powerdown), "getting powerdown GPIO\n"); - } - - pm_runtime_set_suspended(dev); - pm_runtime_enable(dev); - pm_runtime_set_autosuspend_delay(dev, 1000); - pm_runtime_use_autosuspend(dev); - - ret = ov2680_s_config(&sensor->sd); - if (ret) { - ov2680_remove(client); - return ret; - } - - sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; - sensor->pad.flags = MEDIA_PAD_FL_SOURCE; - sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; - sensor->sd.fwnode = sensor->ep_fwnode; - - ret = ov2680_init_controls(sensor); - if (ret) { - ov2680_remove(client); - return ret; - } - - ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); - if (ret) { - ov2680_remove(client); - return ret; - } - - sensor->mode.crop = ov2680_default_crop; - ov2680_fill_format(sensor, &sensor->mode.fmt, OV2680_NATIVE_WIDTH, OV2680_NATIVE_HEIGHT); - ov2680_calc_mode(sensor); - - ret = v4l2_async_register_subdev_sensor(&sensor->sd); - if (ret) { - ov2680_remove(client); - return ret; - } - - return 0; -} - -static int ov2680_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - - gpiod_set_value_cansleep(sensor->powerdown, 1); - return 0; -} - -static int ov2680_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov2680_dev *sensor = to_ov2680_sensor(sd); - - /* according to DS, at least 5ms is needed after DOVDD (enabled by ACPI) */ - usleep_range(5000, 6000); - - gpiod_set_value_cansleep(sensor->powerdown, 0); - - /* according to DS, 20ms is needed between PWDN and i2c access */ - msleep(20); - - ov2680_init_registers(sd); - return 0; -} - -static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL); - -static const struct acpi_device_id ov2680_acpi_match[] = { - {"XXOV2680"}, - {"OVTI2680"}, - {}, -}; -MODULE_DEVICE_TABLE(acpi, ov2680_acpi_match); - -static struct i2c_driver ov2680_driver = { - .driver = { - .name = "ov2680", - .pm = pm_sleep_ptr(&ov2680_pm_ops), - .acpi_match_table = ov2680_acpi_match, - }, - .probe = ov2680_probe, - .remove = ov2680_remove, -}; -module_i2c_driver(ov2680_driver); - -MODULE_AUTHOR("Jacky Wang "); -MODULE_DESCRIPTION("A low-level driver for OmniVision 2680 sensors"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h deleted file mode 100644 index 7815522724f7..000000000000 --- a/drivers/staging/media/atomisp/i2c/ov2680.h +++ /dev/null @@ -1,173 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Support for OmniVision OV2680 5M camera sensor. - * - * Copyright (c) 2013 Intel Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - */ - -#ifndef __OV2680_H__ -#define __OV2680_H__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define OV2680_NATIVE_WIDTH 1616 -#define OV2680_NATIVE_HEIGHT 1216 -#define OV2680_NATIVE_START_LEFT 0 -#define OV2680_NATIVE_START_TOP 0 -#define OV2680_ACTIVE_WIDTH 1600 -#define OV2680_ACTIVE_HEIGHT 1200 -#define OV2680_ACTIVE_START_LEFT 8 -#define OV2680_ACTIVE_START_TOP 8 -#define OV2680_MIN_CROP_WIDTH 2 -#define OV2680_MIN_CROP_HEIGHT 2 - -/* 1704 * 1294 * 30fps = 66MHz pixel clock */ -#define OV2680_PIXELS_PER_LINE 1704 -#define OV2680_LINES_PER_FRAME 1294 - -#define OV2680_SKIP_FRAMES 3 - -/* If possible send 16 extra rows / lines to the ISP as padding */ -#define OV2680_END_MARGIN 16 - -/* - * ov2680 device structure. - */ -struct ov2680_dev { - struct v4l2_subdev sd; - struct media_pad pad; - /* Protect against concurrent changes to controls */ - struct mutex lock; - struct device *dev; - struct regmap *regmap; - struct gpio_desc *powerdown; - struct fwnode_handle *ep_fwnode; - bool is_streaming; - - struct ov2680_mode { - struct v4l2_rect crop; - struct v4l2_mbus_framefmt fmt; - bool binning; - u16 h_start; - u16 v_start; - u16 h_end; - u16 v_end; - u16 h_output_size; - u16 v_output_size; - u16 hts; - u16 vts; - } mode; - - struct ov2680_ctrls { - struct v4l2_ctrl_handler handler; - struct v4l2_ctrl *hflip; - struct v4l2_ctrl *vflip; - struct v4l2_ctrl *exposure; - struct v4l2_ctrl *gain; - struct v4l2_ctrl *test_pattern; - } ctrls; -}; - -#define to_ov2680_sensor(x) container_of(x, struct ov2680_dev, sd) - -static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) -{ - struct ov2680_dev *sensor = - container_of(ctrl->handler, struct ov2680_dev, ctrls.handler); - - return &sensor->sd; -} - -static const struct reg_sequence ov2680_global_setting[] = { - /* MIPI PHY, 0x10 -> 0x1c enable bp_c_hs_en_lat and bp_d_hs_en_lat */ - {0x3016, 0x1c}, - - /* PLL MULT bits 0-7, datasheet default 0x37 for 24MHz extclk, use 0x45 for 19.2 Mhz extclk */ - {0x3082, 0x45}, - - /* R MANUAL set exposure (0x01) and gain (0x02) to manual (hw does not do auto) */ - {0x3503, 0x03}, - - /* Analog control register tweaks */ - {0x3603, 0x39}, /* Reset value 0x99 */ - {0x3604, 0x24}, /* Reset value 0x74 */ - {0x3621, 0x37}, /* Reset value 0x44 */ - - /* Sensor control register tweaks */ - {0x3701, 0x64}, /* Reset value 0x61 */ - {0x3705, 0x3c}, /* Reset value 0x21 */ - {0x370c, 0x50}, /* Reset value 0x10 */ - {0x370d, 0xc0}, /* Reset value 0x00 */ - {0x3718, 0x88}, /* Reset value 0x80 */ - - /* PSRAM tweaks */ - {0x3781, 0x80}, /* Reset value 0x00 */ - {0x3784, 0x0c}, /* Reset value 0x00, based on OV2680_R1A_AM10.ovt */ - {0x3789, 0x60}, /* Reset value 0x50 */ - - /* BLC CTRL00 0x01 -> 0x81 set avg_weight to 8 */ - {0x4000, 0x81}, - - /* Set black level compensation range to 0 - 3 (default 0 - 11) */ - {0x4008, 0x00}, - {0x4009, 0x03}, - - /* VFIFO R2 0x00 -> 0x02 set Frame reset enable */ - {0x4602, 0x02}, - - /* MIPI ctrl CLK PREPARE MIN change from 0x26 (38) -> 0x36 (54) */ - {0x481f, 0x36}, - - /* MIPI ctrl CLK LPX P MIN change from 0x32 (50) -> 0x36 (54) */ - {0x4825, 0x36}, - - /* R ISP CTRL2 0x20 -> 0x30, set sof_sel bit */ - {0x5002, 0x30}, - - /* - * Window CONTROL 0x00 -> 0x01, enable manual window control, - * this is necessary for full size flip and mirror support. - */ - {0x5708, 0x01}, - - /* - * DPC CTRL0 0x14 -> 0x3e, set enable_tail, enable_3x3_cluster - * and enable_general_tail bits based OV2680_R1A_AM10.ovt. - */ - {0x5780, 0x3e}, - - /* DPC MORE CONNECTION CASE THRE 0x0c (12) -> 0x02 (2) */ - {0x5788, 0x02}, - - /* DPC GAIN LIST1 0x0f (15) -> 0x08 (8) */ - {0x578e, 0x08}, - - /* DPC GAIN LIST2 0x3f (63) -> 0x0c (12) */ - {0x578f, 0x0c}, - - /* DPC THRE RATIO 0x04 (4) -> 0x00 (0) */ - {0x5792, 0x00}, -}; - -#endif