From patchwork Wed Jan 25 17:37:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115897 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 5526AC27C76 for ; Wed, 25 Jan 2023 17:37:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235844AbjAYRhf (ORCPT ); Wed, 25 Jan 2023 12:37:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236068AbjAYRhe (ORCPT ); Wed, 25 Jan 2023 12:37:34 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D19D818B1D for ; Wed, 25 Jan 2023 09:37:31 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9CA3298C; Wed, 25 Jan 2023 18:37:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668250; bh=eKUzX7f3ssB6e+vxGYoRVT1XBerfqzqH0bftzPhm45I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Pm+MixEI3LSfL67v9em9zQVkTfppXBg3e4GUPEoKjSotjKpFjIl78yku9VjxKWnOL 7uRTyFnaOzkM3KFBCbrUIvaUZ+9EeXu1V0R6kQdo6+S7c36TO1Uem8qqgrCWg2WFFy KBAQia60pjNFI+hQEjuj1g4U8Q2BUMykHl8f0EcA= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 1/8] media: dt-bindings: Add OV5670 Date: Wed, 25 Jan 2023 18:37:00 +0100 Message-Id: <20230125173707.127687-2-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add the bindings documentation for Omnivision OV5670 image sensor. Signed-off-by: Jacopo Mondi --- .../bindings/media/i2c/ovti,ov5670.yaml | 92 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 93 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml diff --git a/Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml b/Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml new file mode 100644 index 000000000000..fa264255b5eb --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/i2c/ovti,ov5670.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Omnivision OV5670 5 Megapixels raw image sensor + +maintainers: + - Jacopo Mondi + +description: |- + The OV5670 is a 5 Megapixels raw image sensor which provides images in 10-bits + RAW BGGR Bayer format on a 2 data lanes MIPI CSI-2 serial interface and is + controlled through an I2C compatible control bus. + +properties: + compatible: + const: ovti,ov5670 + + reg: + maxItems: 1 + + clocks: + description: System clock. From 6 to 27 MHz. + maxItems: 1 + + powerdown-gpios: + description: Reference to the GPIO connected to the PWDNB pin. Active low. + + reset-gpios: + description: Reference to the GPIO connected to the XSHUTDOWN pin. Active low. + maxItems: 1 + + avdd-supply: + description: Analog circuit power. Typically 2.8V. + + dvdd-supply: + description: Digital circuit power. Typically 1.2V. + + dovdd-supply: + description: Digital I/O circuit power. Typically 2.8V or 1.8V. + + port: + $ref: /schemas/graph.yaml#/$defs/port-base + additionalProperties: false + + properties: + endpoint: + $ref: /schemas/media/video-interfaces.yaml# + unevaluatedProperties: false + + properties: + data-lanes: + minItems: 1 + maxItems: 2 + items: + enum: [1, 2] + + clock-noncontinuous: true + +required: + - compatible + - reg + - clocks + - port + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + ov5670: sensor@36 { + compatible = "ovti,ov5670"; + reg = <0x36>; + + clocks = <&sensor_xclk>; + + port { + ov5670_ep: endpoint { + remote-endpoint = <&csi_ep>; + data-lanes = <1 2>; + clock-noncontinuous; + }; + }; + }; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index f61eb221415b..38d8d1d5d536 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15468,6 +15468,7 @@ M: Chiranjeevi Rapolu L: linux-media@vger.kernel.org S: Maintained T: git git://linuxtv.org/media_tree.git +F: Documentation/devicetree/bindings/media/i2c/ovti,ov5670.yaml F: drivers/media/i2c/ov5670.c OMNIVISION OV5675 SENSOR DRIVER From patchwork Wed Jan 25 17:37:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115898 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 21E4FC27C76 for ; Wed, 25 Jan 2023 17:37:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235736AbjAYRhi (ORCPT ); Wed, 25 Jan 2023 12:37:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59770 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236068AbjAYRhh (ORCPT ); Wed, 25 Jan 2023 12:37:37 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CE384B75C for ; Wed, 25 Jan 2023 09:37:35 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 386FB1204; Wed, 25 Jan 2023 18:37:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668250; bh=lsOhnBsueJT5+Vnq0iApg4VIEcToEChO3dFh+KQmPoQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZPitwvscySt5z5wIoPXOeyCVM8n5dYFKxwSSfbLVWhJVENg3kkE43cr5To276sTo7 zCDA8x+bPxRFSiO1BW/c703b5bdGq3JEafYZAUBFMmFDLPYctPjhaqRsybSMAXjSIm oa/fUGbzXFXXVOrcE2DFGMAkFLa24+p+9llxVqLI= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 2/8] media: i2c: ov5670: Allow probing with OF Date: Wed, 25 Jan 2023 18:37:01 +0100 Message-Id: <20230125173707.127687-3-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ov5670 driver currently only supports probing using ACPI matching. Add support for OF and add a missing header inclusion. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5670.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index bc9fc3bc90c2..07a396c8ab68 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include #include @@ -2583,11 +2585,18 @@ static const struct acpi_device_id ov5670_acpi_ids[] = { MODULE_DEVICE_TABLE(acpi, ov5670_acpi_ids); #endif +static const struct of_device_id ov5670_of_ids[] = { + { .compatible = "ovti,ov5670" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ov5670_of_ids); + static struct i2c_driver ov5670_i2c_driver = { .driver = { .name = "ov5670", .pm = &ov5670_pm_ops, .acpi_match_table = ACPI_PTR(ov5670_acpi_ids), + .of_match_table = ov5670_of_ids, }, .probe_new = ov5670_probe, .remove = ov5670_remove, From patchwork Wed Jan 25 17:37:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115899 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 9B601C54EED for ; Wed, 25 Jan 2023 17:37:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236137AbjAYRhj (ORCPT ); Wed, 25 Jan 2023 12:37:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236113AbjAYRhi (ORCPT ); Wed, 25 Jan 2023 12:37:38 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F22C45A360 for ; Wed, 25 Jan 2023 09:37:35 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 346D2188E; Wed, 25 Jan 2023 18:37:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668251; bh=8JU7sJ2ljljJsNbMiSjJN5c8kK/fxi4OzT+BXQnCE0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ogG6TImT7fNLB1N2GUeXBll96dpa8Ac/TAFPxH5fxITZHfXDC39QWro3+nq5JvZqG v8frXZ1tv5T32X4e9I8hvPeYoOz1+HmL6sS8nx43BbvqksXvbImGezoZfkTiE8nWp8 UWourEJNqLRUilLbLNpbzWIjo7vIybArwMRTvS8k= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 3/8] media: i2c: ov5670: Probe clocks with OF Date: Wed, 25 Jan 2023 18:37:02 +0100 Message-Id: <20230125173707.127687-4-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support for probing the main system clock using the common clock framework and its OF bindings. Maintain ACPI compatibility by falling back to parse 'clock-frequency'. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5670.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 07a396c8ab68..c8beb2bc3d0f 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -2,6 +2,7 @@ // Copyright (c) 2017 Intel Corporation. #include +#include #include #include #include @@ -2475,13 +2476,10 @@ static int ov5670_probe(struct i2c_client *client) struct ov5670 *ov5670; const char *err_msg; u32 input_clk = 0; + struct clk *clk; bool full_power; int ret; - device_property_read_u32(&client->dev, "clock-frequency", &input_clk); - if (input_clk != 19200000) - return -EINVAL; - ov5670 = devm_kzalloc(&client->dev, sizeof(*ov5670), GFP_KERNEL); if (!ov5670) { ret = -ENOMEM; @@ -2489,6 +2487,25 @@ static int ov5670_probe(struct i2c_client *client) goto error_print; } + /* OF uses the common clock framework, ACPI uses "clock-frequency". */ + if (is_of_node(dev_fwnode(&client->dev))) { + clk = devm_clk_get(&client->dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(&client->dev, PTR_ERR(clk), + "error getting clock\n"); + + input_clk = clk_get_rate(clk); + } else { + device_property_read_u32(&client->dev, "clock-frequency", + &input_clk); + } + + if (input_clk != 19200000) { + dev_err(&client->dev, + "Unsupported clock frequency %u\n", input_clk); + return -EINVAL; + } + /* Initialize subdev */ v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops); From patchwork Wed Jan 25 17:37:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115901 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 524F8C61D97 for ; Wed, 25 Jan 2023 17:37:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236141AbjAYRhl (ORCPT ); Wed, 25 Jan 2023 12:37:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236117AbjAYRhk (ORCPT ); Wed, 25 Jan 2023 12:37:40 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03EE7577EA for ; Wed, 25 Jan 2023 09:37:39 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C74DB1935; Wed, 25 Jan 2023 18:37:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668252; bh=7Ur6WazrHGmAkomdY6iX3LBpNO0v+G+W0eprodEVILQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dVs0I570KxvaTH8hT3KQDm4VSn/ahKdyX2Ou5U6IX9NLTMFV+bVOzc5A5hai6VY3r 9O6gD/875umiGwevKH+sZyLktdWN/pYoiYYBLrkSCJAODooi3l3U8dg86T6e9LVc/W MjJ8ofr5biQc9dBOnU9D90ueJKA7DmpzZHnLup14= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 4/8] media: i2c: ov5670: Probe regulators Date: Wed, 25 Jan 2023 18:37:03 +0100 Message-Id: <20230125173707.127687-5-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The OV5670 has three power supplies (AVDD, DOVDD and DVDD). Probe them in the driver to prepare controlling with runtime_pm operations. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5670.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index c8beb2bc3d0f..95bdbf628556 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,14 @@ struct ov5670_link_freq_config { const struct ov5670_reg_list reg_list; }; +static const char * const ov5670_supply_names[] = { + "avdd", /* Analog power */ + "dvdd", /* Digital power */ + "dovdd", /* Digital output power */ +}; + +#define OV5670_NUM_SUPPLIES ARRAY_SIZE(ov5670_supply_names) + struct ov5670_mode { /* Frame width in pixels */ u32 width; @@ -1831,6 +1840,9 @@ struct ov5670 { /* Current mode */ const struct ov5670_mode *cur_mode; + /* Regulators */ + struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES]; + /* To serialize asynchronus callbacks */ struct mutex mutex; @@ -2471,6 +2483,18 @@ static const struct v4l2_subdev_internal_ops ov5670_internal_ops = { .open = ov5670_open, }; +static int ov5670_regulators_probe(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + unsigned int i; + + for (i = 0; i < OV5670_NUM_SUPPLIES; i++) + ov5670->supplies[i].supply = ov5670_supply_names[i]; + + return devm_regulator_bulk_get(&client->dev, OV5670_NUM_SUPPLIES, + ov5670->supplies); +} + static int ov5670_probe(struct i2c_client *client) { struct ov5670 *ov5670; @@ -2509,6 +2533,12 @@ static int ov5670_probe(struct i2c_client *client) /* Initialize subdev */ v4l2_i2c_subdev_init(&ov5670->sd, client, &ov5670_subdev_ops); + ret = ov5670_regulators_probe(ov5670); + if (ret) { + err_msg = "Regulators probe failed"; + goto error_print; + } + full_power = acpi_dev_state_d0(&client->dev); if (full_power) { /* Check module identity */ From patchwork Wed Jan 25 17:37:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115900 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 EB2E7C54E94 for ; Wed, 25 Jan 2023 17:37:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236181AbjAYRhl (ORCPT ); Wed, 25 Jan 2023 12:37:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59846 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236141AbjAYRhk (ORCPT ); Wed, 25 Jan 2023 12:37:40 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 444285867A for ; Wed, 25 Jan 2023 09:37:39 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 66BF31AEF; Wed, 25 Jan 2023 18:37:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668252; bh=BycciKnCJJNO55QmqQMo4O3x4cDe5k+KPzmD9tgvbvs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kkSfgkrjJSDn9q6lR+Z6V3v95B9glIkeatc9XTQsG/rQCmgu2Qz3esJ4QPIysX8Iu mkCbJeuqp3TvEpboMSlacWOeN30c7jk/Kqpoc/dfhi23mTCdT8HCLYTFhdHP0lhbL1 Wp/sPuG2tKjQuHQRwUZFunSOf2fRUDoHDIAaB9VI= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 5/8] media: i2c: ov5670: Probe GPIOs Date: Wed, 25 Jan 2023 18:37:04 +0100 Message-Id: <20230125173707.127687-6-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The OV5670 has a powerdown and reset pin, named respectively "PWDN" and "XSHUTDOWN". Optionally probe the gpios connected to the pins during the driver probe routine. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5670.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 95bdbf628556..6843b2d9a2d4 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -1843,6 +1844,10 @@ struct ov5670 { /* Regulators */ struct regulator_bulk_data supplies[OV5670_NUM_SUPPLIES]; + /* Power-down and reset gpios. */ + struct gpio_desc *pwdn_gpio; /* PWDNB pin. */ + struct gpio_desc *reset_gpio; /* XSHUTDOWN pin. */ + /* To serialize asynchronus callbacks */ struct mutex mutex; @@ -2495,6 +2500,23 @@ static int ov5670_regulators_probe(struct ov5670 *ov5670) ov5670->supplies); } +static int ov5670_gpio_probe(struct ov5670 *ov5670) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); + + ov5670->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown", + GPIOD_OUT_LOW); + if (IS_ERR(ov5670->pwdn_gpio)) + return PTR_ERR(ov5670->pwdn_gpio); + + ov5670->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(ov5670->reset_gpio)) + return PTR_ERR(ov5670->reset_gpio); + + return 0; +} + static int ov5670_probe(struct i2c_client *client) { struct ov5670 *ov5670; @@ -2539,6 +2561,12 @@ static int ov5670_probe(struct i2c_client *client) goto error_print; } + ret = ov5670_gpio_probe(ov5670); + if (ret) { + err_msg = "GPIO probe failed"; + goto error_print; + } + full_power = acpi_dev_state_d0(&client->dev); if (full_power) { /* Check module identity */ From patchwork Wed Jan 25 17:37:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115902 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 EC0DCC54EED for ; Wed, 25 Jan 2023 17:37:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236186AbjAYRhn (ORCPT ); Wed, 25 Jan 2023 12:37:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59878 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236117AbjAYRhm (ORCPT ); Wed, 25 Jan 2023 12:37:42 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 44547577E8 for ; Wed, 25 Jan 2023 09:37:41 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 05E5F1BB9; Wed, 25 Jan 2023 18:37:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668253; bh=zTekOIoZq1te1NrNPvqkylYaTxPFdwnY3EGVDnjt1dA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bkD0r4ETNfjBsndN00EreaniVj6w2wd6QTwtHKl3VSxohlm0GSKINpCH0N+D6nQoD qOe1T/NbcZhkb4fHnvLp97anZ+w2q/6JaiZD71brH7FU2b4OmikRUJPo7F+4sKs+cS Jk5iZthDpAFi/Amp2Z3intV3y4b0ba/0zt+BPfzQ= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 6/8] media: i2c: ov5670: Add runtime_pm operations Date: Wed, 25 Jan 2023 18:37:05 +0100 Message-Id: <20230125173707.127687-7-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement the power up and power down routines and install them as runtime_pm handler for runtime_suspend and runtime_resume operations. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5670.c | 61 ++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 6843b2d9a2d4..0a530b9edd3c 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1,8 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2017 Intel Corporation. +#include + #include #include +#include #include #include #include @@ -15,6 +18,8 @@ #include #include +#define OV5670_XCLK_FREQ 19200000 + #define OV5670_REG_CHIP_ID 0x300a #define OV5670_CHIP_ID 0x005670 @@ -2424,6 +2429,41 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) return ret; } +static int __maybe_unused ov5670_runtime_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5670 *ov5670 = to_ov5670(sd); + unsigned long delay_us; + int ret; + + ret = regulator_bulk_enable(OV5670_NUM_SUPPLIES, ov5670->supplies); + if (ret) + return ret; + + gpiod_set_value_cansleep(ov5670->pwdn_gpio, 0); + gpiod_set_value_cansleep(ov5670->reset_gpio, 0); + + /* 8192 * 2 clock pulses before the first SCCB transaction. */ + delay_us = DIV_ROUND_UP(8192 * 2, OV5670_XCLK_FREQ / 1000 / 1000); + fsleep(delay_us); + + return 0; +} + +static int __maybe_unused ov5670_runtime_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct ov5670 *ov5670 = to_ov5670(sd); + + gpiod_set_value_cansleep(ov5670->reset_gpio, 1); + gpiod_set_value_cansleep(ov5670->pwdn_gpio, 1); + regulator_bulk_disable(OV5670_NUM_SUPPLIES, ov5670->supplies); + + return 0; +} + static int __maybe_unused ov5670_suspend(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); @@ -2546,7 +2586,7 @@ static int ov5670_probe(struct i2c_client *client) &input_clk); } - if (input_clk != 19200000) { + if (input_clk != OV5670_XCLK_FREQ) { dev_err(&client->dev, "Unsupported clock frequency %u\n", input_clk); return -EINVAL; @@ -2569,12 +2609,21 @@ static int ov5670_probe(struct i2c_client *client) full_power = acpi_dev_state_d0(&client->dev); if (full_power) { + ret = ov5670_runtime_resume(&client->dev); + if (ret) { + err_msg = "Power up failed"; + goto error_print; + } + /* Check module identity */ ret = ov5670_identify_module(ov5670); if (ret) { err_msg = "ov5670_identify_module() error"; - goto error_print; + goto error_power_off; } + + /* Set the device's state to active if it's in D0 state. */ + pm_runtime_set_active(&client->dev); } mutex_init(&ov5670->mutex); @@ -2611,9 +2660,6 @@ static int ov5670_probe(struct i2c_client *client) ov5670->streaming = false; - /* Set the device's state to active if it's in D0 state. */ - if (full_power) - pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); @@ -2628,6 +2674,9 @@ static int ov5670_probe(struct i2c_client *client) error_mutex_destroy: mutex_destroy(&ov5670->mutex); +error_power_off: + ov5670_runtime_suspend(&client->dev); + error_print: dev_err(&client->dev, "%s: %s %d\n", __func__, err_msg, ret); @@ -2644,11 +2693,13 @@ static void ov5670_remove(struct i2c_client *client) v4l2_ctrl_handler_free(sd->ctrl_handler); mutex_destroy(&ov5670->mutex); + ov5670_runtime_suspend(&client->dev); pm_runtime_disable(&client->dev); } static const struct dev_pm_ops ov5670_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(ov5670_suspend, ov5670_resume) + SET_RUNTIME_PM_OPS(ov5670_runtime_suspend, ov5670_runtime_resume, NULL) }; #ifdef CONFIG_ACPI From patchwork Wed Jan 25 17:37:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115903 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 D843AC54E94 for ; Wed, 25 Jan 2023 17:37:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236176AbjAYRhq (ORCPT ); Wed, 25 Jan 2023 12:37:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236190AbjAYRhp (ORCPT ); Wed, 25 Jan 2023 12:37:45 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94AD35867A for ; Wed, 25 Jan 2023 09:37:41 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 985B02731; Wed, 25 Jan 2023 18:37:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668254; bh=vcRT+SjdZCUXl5wyF/UY3elIxusJX0vFOFyDjJDcgP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qh0VqsT3XY6yHQUAUBFv+x4lGySpV5cUCWwUnzLldzHFTCxFsz4+1SrRn3hd6qRIy Z9+gwzs2T2kPnHhxU4St+nvfnGd3UKyyG3Io4xEmra/P5m2aqCfHKx5x03w37TqToq jj+KamgTXd3UR7dLDyWoZTDdiI5WzM4gwdpSNdvY= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER) Subject: [PATCH v4 7/8] media: i2c: ov5670: Implement init_cfg Date: Wed, 25 Jan 2023 18:37:06 +0100 Message-Id: <20230125173707.127687-8-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Implement the .init_cfg() pad operation and initialize the default format with the default full resolution mode 2592x1944. With .init_cfg() pad operation implemented the deprecated .open() internal operation can now be dropped. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/ov5670.c | 46 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 0a530b9edd3c..a79582b48a74 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1960,27 +1960,6 @@ static int ov5670_write_reg_list(struct ov5670 *ov5670, return ov5670_write_regs(ov5670, r_list->regs, r_list->num_of_regs); } -/* Open sub-device */ -static int ov5670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -{ - struct ov5670 *ov5670 = to_ov5670(sd); - struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->state, 0); - - mutex_lock(&ov5670->mutex); - - /* Initialize try_fmt */ - try_fmt->width = ov5670->cur_mode->width; - try_fmt->height = ov5670->cur_mode->height; - try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; - try_fmt->field = V4L2_FIELD_NONE; - - /* No crop or compose */ - mutex_unlock(&ov5670->mutex); - - return 0; -} - static int ov5670_update_digital_gain(struct ov5670 *ov5670, u32 d_gain) { int ret; @@ -2180,6 +2159,25 @@ static int ov5670_init_controls(struct ov5670 *ov5670) return ret; } +static int ov5670_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_mbus_framefmt *fmt = + v4l2_subdev_get_try_format(sd, state, 0); + const struct ov5670_mode *default_mode = &supported_modes[0]; + + fmt->width = default_mode->width; + fmt->height = default_mode->height; + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SRGB); + fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; + fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB); + + return 0; +} + static int ov5670_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) @@ -2503,6 +2501,7 @@ static const struct v4l2_subdev_video_ops ov5670_video_ops = { }; static const struct v4l2_subdev_pad_ops ov5670_pad_ops = { + .init_cfg = ov5670_init_cfg, .enum_mbus_code = ov5670_enum_mbus_code, .get_fmt = ov5670_get_pad_format, .set_fmt = ov5670_set_pad_format, @@ -2524,10 +2523,6 @@ static const struct media_entity_operations ov5670_subdev_entity_ops = { .link_validate = v4l2_subdev_link_validate, }; -static const struct v4l2_subdev_internal_ops ov5670_internal_ops = { - .open = ov5670_open, -}; - static int ov5670_regulators_probe(struct ov5670 *ov5670) { struct i2c_client *client = v4l2_get_subdevdata(&ov5670->sd); @@ -2637,7 +2632,6 @@ static int ov5670_probe(struct i2c_client *client) goto error_mutex_destroy; } - ov5670->sd.internal_ops = &ov5670_internal_ops; ov5670->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; ov5670->sd.entity.ops = &ov5670_subdev_entity_ops; From patchwork Wed Jan 25 17:37:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13115904 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 4613DC54E94 for ; Wed, 25 Jan 2023 17:37:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236190AbjAYRhu (ORCPT ); Wed, 25 Jan 2023 12:37:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60288 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236214AbjAYRhs (ORCPT ); Wed, 25 Jan 2023 12:37:48 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 002B0212C for ; Wed, 25 Jan 2023 09:37:43 -0800 (PST) Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3654C3112; Wed, 25 Jan 2023 18:37:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1674668254; bh=22v5coPnrKuT0FgmhfBU0M13zVFSBY68DddBPCbQBaw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PfGw5k4xZ6jyB/G/J8SPUTGPimK5DoboTCWJ+4DEyTEH0lO2K2qbFilwlx/npXzZl UaDySBRPowE84DsYDmppI8Om1S9+ZkPwOzJw395t7RUc+lam3YYlA+Ut/u2jdzs4qY ZZIeRzmtqES2WKh9pRSpziXyfgaoPjss1D/qW6+s= From: Jacopo Mondi To: Chiranjeevi Rapolu , Luca Weiss Cc: Jacopo Mondi , laurent.pinchart@ideasonboard.com, sakari.ailus@iki.fi, Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:OMNIVISION OV5670 SENSOR DRIVER), Jean-Michel Hautbois Subject: [PATCH v4 8/8] media: i2c: ov5670: Add .get_selection() support Date: Wed, 25 Jan 2023 18:37:07 +0100 Message-Id: <20230125173707.127687-9-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> References: <20230125173707.127687-1-jacopo.mondi@ideasonboard.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Jean-Michel Hautbois Add support for the .get_selection() pad operation to the ov5670 sensor driver. Report the native sensor size (pixel array), the crop bounds (readable pixel array area) and the current and default analog crop rectangles. Currently all driver's modes use an analog crop rectangle of size [12, 4, 2600, 1952]. Instead of hardcoding the value in the operation implementation, ad an .analog_crop field to the sensor's modes definitions, to make sure that if any mode gets added, its crop rectangle will be defined as well. While at it re-sort the modes' field definition order to match the declaration order and initialize the crop rectangle in init_cfg(). Signed-off-by: Jean-Michel Hautbois Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- drivers/media/i2c/ov5670.c | 89 +++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 6 deletions(-) -- 2.39.0 diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index a79582b48a74..90ab9fb7d4c8 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -75,6 +75,10 @@ #define OV5670_REG_VALUE_16BIT 2 #define OV5670_REG_VALUE_24BIT 3 +/* Pixel Array */ +#define OV5670_NATIVE_WIDTH 2624 +#define OV5670_NATIVE_HEIGHT 1980 + /* Initial number of frames to skip to avoid possible garbage */ #define OV5670_NUM_OF_SKIP_FRAMES 2 @@ -117,10 +121,25 @@ struct ov5670_mode { /* Link frequency needed for this resolution */ u32 link_freq_index; + /* Analog crop rectangle */ + const struct v4l2_rect *analog_crop; + /* Sensor register settings for this resolution */ const struct ov5670_reg_list reg_list; }; +/* + * All the modes supported by the driver are obtained by subsampling the + * full pixel array. The below values are reflected in registers from + * 03800-0x3807 in the modes register-value tables. + */ +static const struct v4l2_rect ov5670_analog_crop = { + .left = 12, + .top = 4, + .width = 2600, + .height = 1952, +}; + static const struct ov5670_reg mipi_data_rate_840mbps[] = { {0x0300, 0x04}, {0x0301, 0x00}, @@ -1768,66 +1787,73 @@ static const struct ov5670_mode supported_modes[] = { .height = 1944, .vts_def = OV5670_VTS_30FPS, .vts_min = OV5670_VTS_30FPS, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs), .regs = mode_2592x1944_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 1296, .height = 972, .vts_def = OV5670_VTS_30FPS, .vts_min = 996, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1296x972_regs), .regs = mode_1296x972_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 648, .height = 486, .vts_def = OV5670_VTS_30FPS, .vts_min = 516, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_648x486_regs), .regs = mode_648x486_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 2560, .height = 1440, .vts_def = OV5670_VTS_30FPS, .vts_min = OV5670_VTS_30FPS, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_2560x1440_regs), .regs = mode_2560x1440_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 1280, .height = 720, .vts_def = OV5670_VTS_30FPS, .vts_min = 1020, + + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_1280x720_regs), .regs = mode_1280x720_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, }, { .width = 640, .height = 360, .vts_def = OV5670_VTS_30FPS, .vts_min = 510, + .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, + .analog_crop = &ov5670_analog_crop, .reg_list = { .num_of_regs = ARRAY_SIZE(mode_640x360_regs), .regs = mode_640x360_regs, }, - .link_freq_index = OV5670_LINK_FREQ_422MHZ_INDEX, } }; @@ -2165,6 +2191,7 @@ static int ov5670_init_cfg(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt = v4l2_subdev_get_try_format(sd, state, 0); const struct ov5670_mode *default_mode = &supported_modes[0]; + struct v4l2_rect *crop = v4l2_subdev_get_try_crop(sd, state, 0); fmt->width = default_mode->width; fmt->height = default_mode->height; @@ -2175,6 +2202,8 @@ static int ov5670_init_cfg(struct v4l2_subdev *sd, fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SRGB); + *crop = *default_mode->analog_crop; + return 0; } @@ -2496,6 +2525,52 @@ static const struct v4l2_subdev_core_ops ov5670_core_ops = { .unsubscribe_event = v4l2_event_subdev_unsubscribe, }; +static const struct v4l2_rect * +__ov5670_get_pad_crop(struct ov5670 *sensor, struct v4l2_subdev_state *state, + unsigned int pad, enum v4l2_subdev_format_whence which) +{ + const struct ov5670_mode *mode = sensor->cur_mode; + + switch (which) { + case V4L2_SUBDEV_FORMAT_TRY: + return v4l2_subdev_get_try_crop(&sensor->sd, state, pad); + case V4L2_SUBDEV_FORMAT_ACTIVE: + return mode->analog_crop; + } + + return NULL; +} + +static int ov5670_get_selection(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct ov5670 *sensor = to_ov5670(subdev); + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + mutex_lock(&sensor->mutex); + sel->r = *__ov5670_get_pad_crop(sensor, state, sel->pad, + sel->which); + mutex_unlock(&sensor->mutex); + break; + case V4L2_SEL_TGT_NATIVE_SIZE: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = OV5670_NATIVE_WIDTH; + sel->r.height = OV5670_NATIVE_HEIGHT; + break; + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r = ov5670_analog_crop; + break; + default: + return -EINVAL; + } + + return 0; +} + static const struct v4l2_subdev_video_ops ov5670_video_ops = { .s_stream = ov5670_set_stream, }; @@ -2506,6 +2581,8 @@ static const struct v4l2_subdev_pad_ops ov5670_pad_ops = { .get_fmt = ov5670_get_pad_format, .set_fmt = ov5670_set_pad_format, .enum_frame_size = ov5670_enum_frame_size, + .get_selection = ov5670_get_selection, + .set_selection = ov5670_get_selection, }; static const struct v4l2_subdev_sensor_ops ov5670_sensor_ops = {